00001
00007 #include <stdarg.h>
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <signal.h>
00012 #include <time.h>
00013
00014 #include "config.h"
00015 #ifdef CP_HAS_SYS_TIME_H
00016 #include <sys/time.h>
00017 #endif
00018 #include <errno.h>
00019
00020 #ifdef _WINDOWS
00021 #include <Windows.h>
00022 #endif
00023
00024 #include "log.h"
00025 #include "util.h"
00026 #include "common.h"
00027 #include "hashtable.h"
00028
00029 static FILE *logfile = NULL;
00030 static char *log_filename = NULL;
00031 static int loglevel = 1;
00032
00033 static cp_hashtable *thread_id;
00034 long thread_count;
00035
00036 #define PRECISE_TIME_FACTOR 1000
00037
00038 typedef struct _error_code_legend
00039 {
00040 int code;
00041 char *msg;
00042 } error_code_legend;
00043
00044 error_code_legend error_messages[] =
00045 {
00046 {CP_MEMORY_ALLOCATION_FAILURE, "MEMORY ALLOCATION FAILURE"},
00047 {CP_INVALID_FUNCTION_POINTER, "INVALID FUNCTION POINTER"},
00048 {CP_THREAD_CREATION_FAILURE, "THREAD CREATION FAILURE"},
00049 {CP_INITIALIZATION_FAILURE, "INITIALIZATION FAILURE"},
00050
00051 {CP_LOADLIB_FAILED, "LOADLIB FAILED"},
00052 {CP_LOADFN_FAILED, "LOADFN FAILED"},
00053 {CP_MODULE_NOT_LOADED, "MODULE NOT LOADED"},
00054
00055 {CP_IO_ERROR, "IO ERROR"},
00056 {CP_OPEN_PORT_FAILED, "OPEN PORT FAILED"},
00057 {CP_HTTP_FETCH_FAILED, "HTTP FETCH FAILED"},
00058 {CP_INVALID_RESPONSE, "INVALID RESPONSE"},
00059 {CP_HTTP_EMPTY_REQUEST, "EMPTY HTTP REQUEST"},
00060 {CP_HTTP_INVALID_REQUEST_LINE, "INVALID HTTP REQUEST LINE"},
00061 {CP_HTTP_INVALID_STATUS_LINE, "INVALID HTTP STATUS LINE"},
00062 {CP_HTTP_UNKNOWN_REQUEST_TYPE, "UNKNOWN HTTP REQUEST TYPE"},
00063 {CP_HTTP_INVALID_URI, "INVALID URI"},
00064 {CP_HTTP_INVALID_URL, "INVALID URL"},
00065 {CP_HTTP_VERSION_NOT_SPECIFIED, "HTTP VERSION NOT SPECIFIED"},
00066 {CP_HTTP_1_1_HOST_NOT_SPECIFIED, "HTTP 1.1 HOST NOT SPECIFIED"},
00067 {CP_HTTP_INCORRECT_REQUEST_BODY_LENGTH, "INCORRECT HTTP REQUEST BODY LENGTH"},
00068 {CP_SSL_CTX_INITIALIZATION_ERROR, "SSL CONTEXT INITIALIZATION ERROR"},
00069 {CP_SSL_HANDSHAKE_FAILED, "SSL HANDSHAKE FAILED"},
00070 {CP_SSL_VERIFICATION_ERROR, "SSL VERIFICATION ERROR"},
00071
00072 {CP_LOG_FILE_OPEN_FAILURE, "LOG FILE OPEN FAILURE"},
00073 {CP_LOG_NOT_OPEN, "LOG NOT OPEN"},
00074
00075 {CP_INVALID_VALUE, "INVALID VALUE"},
00076 {CP_MISSING_PARAMETER, "MISSING PARAMETER"},
00077 {CP_BAD_PARAMETER_SET, "BAD PARAMETER SET"},
00078 {CP_ITEM_EXISTS, "ITEM EXISTS"},
00079 {CP_ITEM_DOES_NOT_EXIST, "ITEM DOES NOT EXIST"},
00080 {CP_UNHANDLED_SIGNAL, "UNHANDLED SIGNAL"},
00081 {CP_FILE_NOT_FOUND, "FILE NOT FOUND"},
00082 {CP_METHOD_NOT_IMPLEMENTED, "METHOD NOT IMPLEMENTED"},
00083 {CP_INVALID_FILE_OFFSET, "INVALID FILE OFFSET"},
00084 {CP_CORRUPT_FILE, "CORRUPT FILE"},
00085 {CP_CORRUPT_INDEX, "CORRUPT INDEX"},
00086 {CP_UNIQUE_INDEX_VIOLATION, "UNIQUE INDEX VIOLATION"},
00087
00088 {CP_REGEX_COMPILATION_FAILURE, "INVALID REGULAR EXPRESSION"},
00089 {CP_COMPILATION_FAILURE, "COMPILATION FAILED"},
00090
00091 {CP_DBMS_NO_DRIVER, "NO DRIVER"},
00092 {CP_DBMS_CONNECTION_FAILURE, "DBMS CONNECTION FAILED"},
00093 {CP_DBMS_QUERY_FAILED, "DBMS QUERY FAILED"},
00094 {CP_DBMS_CLIENT_ERROR, "DBMS CLIENT ERROR"},
00095 {CP_DBMS_STATEMENT_ERROR, "DBMS STATEMENT ERROR"}
00096 };
00097
00098 static cp_hashtable *error_message_lookup;
00099
00100 static long get_thread_serial(long tno)
00101 {
00102 long *num;
00103
00104 if (thread_id == NULL) return 0;
00105
00106 num = cp_hashtable_get(thread_id, &tno);
00107
00108 if (num == NULL)
00109 {
00110 long *key;
00111 num = malloc(sizeof(long));
00112 if (num == NULL)
00113 {
00114 cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread mapping number");
00115 return -1L;
00116 }
00117 key = malloc(sizeof(long));
00118 if (key == NULL)
00119 {
00120 cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread mapping key");
00121 return -1L;
00122 }
00123
00124 *num = ++thread_count;
00125 *key = tno;
00126 cp_hashtable_put(thread_id, key, num);
00127 }
00128
00129 return *num;
00130 }
00131
00132 #ifdef SIGHUP
00133 void cp_log_default_signal_handler(int sig)
00134 {
00135 if (sig == SIGHUP)
00136 {
00137 signal(SIGHUP, cp_log_default_signal_handler);
00138 #ifdef __TRACE__
00139 DEBUGMSG("SIGHUP received - reopenning log file [%s]",
00140 log_filename ? log_filename : "NULL");
00141 #endif
00142 cp_log_reopen();
00143 }
00144 }
00145 #endif
00146
00147 static int log_closing = 0;
00148
00149 int cp_log_init(char *filename, int verbosity)
00150 {
00151 int i, err_code_count;
00152 unsigned long thread_no;
00153 #ifdef SIGHUP
00154 struct sigaction act;
00155 #endif
00156
00157 log_filename = strdup(filename);
00158 logfile = fopen(filename, "a+");
00159 if (logfile == NULL)
00160 return CP_LOG_FILE_OPEN_FAILURE;
00161
00162 loglevel = verbosity;
00163
00164 err_code_count = sizeof(error_messages) / sizeof(error_code_legend);
00165 error_message_lookup =
00166 cp_hashtable_create_by_mode(COLLECTION_MODE_NOSYNC,
00167 err_code_count * 2,
00168 cp_hash_int,
00169 cp_hash_compare_int);
00170 for (i = 0; i < err_code_count; i++)
00171 {
00172 error_code_legend *entry = &error_messages[i];
00173 cp_hashtable_put(error_message_lookup, &entry->code, entry->msg);
00174 }
00175
00176 thread_id =
00177 cp_hashtable_create_by_option(COLLECTION_MODE_DEEP, 10,
00178 cp_hash_long, cp_hash_compare_long,
00179 NULL, free, NULL, free);
00180
00181 thread_count = 0;
00182
00183 thread_no = (unsigned long) cp_thread_self();
00184 get_thread_serial(thread_no);
00185
00186 log_closing = 0;
00187
00188 #ifdef SIGHUP
00189 act.sa_handler = cp_log_default_signal_handler;
00190 sigemptyset(&act.sa_mask);
00191 act.sa_flags = 0;
00192 sigaction(SIGHUP, &act, NULL);
00193 #endif
00194
00195
00196 return 0;
00197 }
00198
00199 int cp_log_reopen()
00200 {
00201 int rc = 0;
00202
00203 if (logfile)
00204 {
00205 fflush(logfile);
00206 fclose(logfile);
00207 logfile = fopen(log_filename, "a+");
00208 if (logfile == NULL)
00209 rc = CP_LOG_FILE_OPEN_FAILURE;
00210 }
00211 else
00212 rc = CP_LOG_NOT_OPEN;
00213
00214 return rc;
00215 }
00216
00217 int cp_log_close()
00218 {
00219 int rc;
00220
00221 if (log_closing) return 0;
00222 log_closing = 1;
00223
00224 if (logfile == NULL) return 0;
00225 rc = fclose(logfile);
00226 logfile = NULL;
00227 if (log_filename)
00228 {
00229 free(log_filename);
00230 log_filename = NULL;
00231 }
00232
00233 cp_hashtable_destroy(error_message_lookup);
00234
00235 if (thread_id)
00236 {
00237 cp_hashtable_destroy(thread_id);
00238 thread_id = NULL;
00239 }
00240
00241 return rc;
00242 }
00243
00244 void cp_log(const char *fmt, ...)
00245 {
00246 va_list argp;
00247
00248 va_start(argp, fmt);
00249 vprintf(fmt, argp);
00250 va_end(argp);
00251
00252 if (logfile == NULL) return;
00253
00254 va_start(argp, fmt);
00255 vfprintf(logfile, fmt, argp);
00256 va_end(argp);
00257 }
00258
00259 void cp_nlog(size_t len, const char *fmt, ...)
00260 {
00261 va_list argp;
00262 char *buf = malloc(len + 1);
00263
00264 if (buf == NULL) return;
00265
00266 if (logfile == NULL) return;
00267
00268 va_start(argp, fmt);
00269 #ifdef CP_HAS_VSNPRINTF
00270 vsnprintf(buf, len, fmt, argp);
00271 #else
00272 vsprintf(buf, fmt, argp);
00273 #endif
00274 va_end(argp);
00275
00276 buf[len] = '\0';
00277 fprintf(logfile, buf);
00278 free(buf);
00279 }
00280
00281 static char *cc_time_format = DEFAULT_TIME_FORMAT;
00282
00283
00284 void cp_log_set_time_format(char *time_format)
00285 {
00286 cc_time_format = time_format;
00287 }
00288
00289 static void cc_printout(char *type, char *fmt, va_list argp)
00290 {
00291 char buf[MAX_LOG_MESSAGE_LEN];
00292 struct tm *local;
00293 char timestr[256];
00294 unsigned long tid;
00295 unsigned long thread_no;
00296
00297 #ifdef PRECISE_TIME
00298 struct timeval now;
00299 gettimeofday(&now, NULL);
00300
00301 local = localtime(&now.tv_sec);
00302 #else //precise
00303 time_t now;
00304 time(&now);
00305 local = localtime(&now);
00306 #endif //precise
00307
00308
00309
00310 tid = (unsigned long) cp_thread_self();
00311 thread_no = get_thread_serial(tid);
00312
00313 strftime(timestr, 256, cc_time_format, local);
00314 #ifdef CP_HAS_VSNPRINTF
00315 vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
00316 #else
00317 vsprintf(buf, fmt, argp);
00318 #endif
00319
00320 #ifdef PRECISE_TIME
00321 printf("%s" PRECISE_TIME_FORMAT " [%lX] %s: %s\n",
00322 timestr, now.tv_usec / PRECISE_TIME_FACTOR, thread_no, type, buf);
00323 if (logfile)
00324 fprintf(logfile, "%s" PRECISE_TIME_FORMAT " [%lX] %s: %s\n",
00325 timestr, now.tv_usec / PRECISE_TIME_FACTOR, thread_no,
00326 type, buf);
00327 #else
00328 printf("%s [%lu] %s: %s\n", timestr, thread_no, type, buf);
00329 if (logfile)
00330 fprintf(logfile, "%s [%lu] %s: %s\n", timestr, thread_no, type, buf);
00331 #endif
00332 if (logfile) fflush(logfile);
00333 }
00334
00335 #ifdef CP_HAS_VARIADIC_MACROS
00336 static void cp_error_printout(char *type, char *fmt, char *file, int line, va_list argp)
00337 #else
00338 static void cp_error_printout(char *type, char *fmt, va_list argp)
00339 #endif
00340 {
00341 char buf[MAX_LOG_MESSAGE_LEN];
00342 struct tm *local;
00343 char timestr[256];
00344 unsigned long tid;
00345 unsigned long thread_no;
00346 #ifdef PRECISE_TIME
00347 struct timeval now;
00348 gettimeofday(&now, NULL);
00349 local = localtime(&now.tv_sec);
00350 #else //precise
00351 time_t now;
00352 time(&now);
00353 local = localtime(&now);
00354 #endif //precise
00355
00356
00357 tid = (unsigned long) cp_thread_self();
00358 thread_no = get_thread_serial(tid);
00359
00360 strftime(timestr, 256, cc_time_format, local);
00361 #ifdef CP_HAS_VSNPRINTF
00362 vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
00363 #else
00364 vsprintf(buf, fmt, argp);
00365 #endif
00366
00367 #ifdef PRECISE_TIME
00368 printf("%s" PRECISE_TIME_FORMAT " [%lX] %s: %s "
00369 #ifdef CP_HAS_VARIADIC_MACROS
00370 "(%s line %d)"
00371 #endif
00372 "\n",
00373 timestr, now.tv_usec / PRECISE_TIME_FACTOR, thread_no,
00374 type, buf
00375 #ifdef CP_HAS_VARIADIC_MACROS
00376 , file, line
00377 #endif
00378 );
00379 if (logfile)
00380 fprintf(logfile, "%s" PRECISE_TIME_FORMAT " [%lX] %s: %s "
00381 #ifdef CP_HAS_VARIADIC_MACROS
00382 "(%s line %d)"
00383 #endif
00384 "\n"
00385 ,timestr, now.tv_usec / PRECISE_TIME_FACTOR, thread_no,
00386 type, buf
00387 #ifdef CP_HAS_VARIADIC_MACROS
00388 , file, line
00389 #endif
00390 );
00391 #else //precise
00392 printf("%s [%lu] %s: %s "
00393 #ifdef CP_HAS_VARIADIC_MACROS
00394 "(%s line %d)"
00395 #endif
00396 "\n", timestr, thread_no, type, buf
00397 #ifdef CP_HAS_VARIADIC_MACROS
00398 , file, line
00399 #endif
00400 );
00401 if (logfile)
00402 fprintf(logfile, "%s [%lu] %s: %s (%s line %d)\n", timestr, thread_no, type, buf, file, line);
00403 #endif //precise
00404 if (logfile) fflush(logfile);
00405 }
00406
00407 #ifdef CP_HAS_VARIADIC_MACROS
00408 void cp_debug_message(char *fmt, char *file, int line, ...)
00409 #else
00410 void cp_debug(char *fmt, ...)
00411 #endif
00412 {
00413 va_list argp;
00414
00415 if (loglevel > LOG_LEVEL_DEBUG) return;
00416
00417
00418 #ifdef CP_HAS_VARIADIC_MACROS
00419 va_start(argp, line);
00420 #else
00421 va_start(argp, fmt);
00422 #endif
00423 cp_error_printout("debug", fmt
00424 #ifdef CP_HAS_VARIADIC_MACROS
00425 , file, line
00426 #endif
00427 , argp);
00428 va_end(argp);
00429 }
00430
00431 void cp_debuginfo(char *fmt, ...)
00432 {
00433 va_list argp;
00434
00435 if (loglevel > LOG_LEVEL_DEBUG) return;
00436
00437 va_start(argp, fmt);
00438 cc_printout("debug", fmt, argp);
00439 va_end(argp);
00440 }
00441
00442 void cp_info(char *fmt, ...)
00443 {
00444 va_list argp;
00445
00446 if (loglevel > LOG_LEVEL_INFO) return;
00447
00448 va_start(argp, fmt);
00449 cc_printout("info", fmt, argp);
00450 va_end(argp);
00451 }
00452
00453 void cp_warn(char *fmt, ...)
00454 {
00455 va_list argp;
00456
00457 if (loglevel > LOG_LEVEL_WARNING) return;
00458
00459 va_start(argp, fmt);
00460 cc_printout("warning", fmt, argp);
00461 va_end(argp);
00462 }
00463
00464 #ifdef CP_HAS_VARIADIC_MACROS
00465 void cp_error_message(int code, char *fmt, char *file, int line, ...)
00466 #else
00467 void cp_error(int code, char *fmt, ...)
00468 #endif
00469 {
00470 va_list argp;
00471 char errcode[256];
00472 char errmsg[224];
00473 char *msg;
00474
00475 if (loglevel > LOG_LEVEL_ERROR) return;
00476
00477
00478 msg = cp_hashtable_get(error_message_lookup, &code);
00479 if (msg)
00480 #ifdef CP_HAS_SNPRINTF
00481 snprintf(errmsg, 224, " - %s", msg);
00482 #else
00483 sprintf(errmsg, " - %s", msg);
00484 #endif
00485 else
00486 errmsg[0] = '\0';
00487
00488 #ifdef CP_HAS_SNPRINTF
00489 snprintf(errcode, 256, "error [%d%s]", code, errmsg);
00490 #else
00491 sprintf(errcode, "error [%d%s]", code, errmsg);
00492 #endif
00493
00494 #ifdef CP_HAS_VARIADIC_MACROS
00495 va_start(argp, line);
00496 #else
00497 va_start(argp, fmt);
00498 #endif
00499 cp_error_printout(errcode, fmt
00500 #ifdef CP_HAS_VARIADIC_MACROS
00501 , file, line
00502 #endif
00503 , argp);
00504 va_end(argp);
00505 }
00506
00507 #ifdef CP_HAS_VARIADIC_MACROS
00508 void cp_perror_message(int code, int errno_code,
00509 char *fmt, char *file, int line, ...)
00510 #else
00511 void cp_perror(int code, int errno_code, char *fmt, ...)
00512 #endif
00513 {
00514 va_list argp;
00515 char errcode[512];
00516 char errmsg[224];
00517 #ifdef CP_HAS_STRERROR_R
00518 char perrmsg[256];
00519 #endif
00520 char *msg;
00521
00522 if (loglevel > LOG_LEVEL_ERROR) return;
00523
00524
00525 msg = cp_hashtable_get(error_message_lookup, &code);
00526 if (msg)
00527 #ifdef CP_HAS_SNPRINTF
00528 snprintf(errmsg, 224, " - %s", msg);
00529 #else
00530 sprintf(errmsg, " - %s", msg);
00531 #endif
00532 else
00533 errmsg[0] = '\0';
00534
00535 #ifdef CP_HAS_STRERROR_R
00536 sprintf(perrmsg, "unknown error");
00537 strerror_r(errno_code, perrmsg, 255);
00538
00539 #ifdef CP_HAS_SNPRINTF
00540 snprintf(errcode, 512, "error [%d%s / %s] -", code, errmsg, perrmsg);
00541 #else
00542 sprintf(errcode, "error [%d%s / %s] -", code, errmsg, perrmsg);
00543 #endif
00544 #else
00545 #ifdef CP_HAS_SNPRINTF
00546 snprintf(errcode, 512, "error [%d%s / %s] -", code, errmsg,
00547 strerror(errno_code));
00548 #else
00549 sprintf(errcode, "error [%d%s / %s] -", code, errmsg,
00550 strerror(errno_code));
00551 #endif
00552 #endif
00553
00554 #ifdef CP_HAS_VARIADIC_MACROS
00555 va_start(argp, line);
00556 #else
00557 va_start(argp, fmt);
00558 #endif
00559 cp_error_printout(errcode, fmt
00560 #ifdef CP_HAS_VARIADIC_MACROS
00561 , file, line
00562 #endif
00563 , argp);
00564 va_end(argp);
00565 }
00566
00567 #ifdef CP_HAS_VARIADIC_MACROS
00568 void cp_fatal_message(int code, char *fmt, char *file, int line, ...)
00569 #else
00570 void cp_fatal(int code, char *fmt, ...)
00571 #endif
00572 {
00573 va_list argp;
00574 char errcode[30];
00575
00576
00577 if (loglevel <= LOG_LEVEL_FATAL)
00578 {
00579 #ifdef CP_HAS_SNPRINTF
00580 snprintf(errcode, 30, "fatal (%d)", code);
00581 #else
00582 sprintf(errcode, "fatal (%d)", code);
00583 #endif
00584 #ifdef CP_HAS_VARIADIC_MACROS
00585 va_start(argp, line);
00586 #else
00587 va_start(argp, fmt);
00588 #endif
00589 cp_error_printout(errcode, fmt
00590 #ifdef CP_HAS_VARIADIC_MACROS
00591 , file, line
00592 #endif
00593 , argp);
00594 va_end(argp);
00595 }
00596
00597 cp_log_close();
00598 fflush(stdout);
00599 fflush(stderr);
00600 exit(code);
00601 }
00602
00603 #ifdef DEBUG
00604 #ifdef CP_HAS_VARIADIC_MACROS
00605 void DEBUGMSG_impl(char *fmt, char *file, int line, ...)
00606 #else
00607 void DEBUGMSG(char *fmt, ...)
00608 #endif
00609 {
00610 va_list argp;
00611
00612 if (loglevel > LOG_LEVEL_DEBUG) return;
00613
00614
00615 #ifdef CP_HAS_VARIADIC_MACROS
00616 va_start(argp, line);
00617 #else
00618 va_start(argp, fmt);
00619 #endif
00620 cp_error_printout("debug", fmt
00621 #ifdef CP_HAS_VARIADIC_MACROS
00622 , file, line
00623 #endif
00624 , argp);
00625 va_end(argp);
00626 }
00627 #endif
00628
00629 void die(int code, const char *fmt, ...)
00630 {
00631 va_list argp;
00632 char buf[MAX_LOG_MESSAGE_LEN];
00633
00634 if (logfile == NULL) logfile = stderr;
00635
00636 va_start(argp, fmt);
00637 #ifdef CP_HAS_VSNPRINTF
00638 vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
00639 #else
00640 vsprintf(buf, fmt, argp);
00641 #endif
00642 va_end(argp);
00643
00644 cp_log(buf);
00645 cp_fatal(code, buf);
00646 }
00647
00648 #define LINELEN 81
00649 #define CHARS_PER_LINE 16
00650
00651 static char *print_char =
00652 " "
00653 " "
00654 " !\"#$%&'()*+,-./"
00655 "0123456789:;<=>?"
00656 "@ABCDEFGHIJKLMNO"
00657 "PQRSTUVWXYZ[\\]^_"
00658 "`abcdefghijklmno"
00659 "pqrstuvwxyz{|}~ "
00660 " "
00661 " "
00662 " ¡¢£¤¥¦§¨©ª«¬®¯"
00663 "°±²³´µ¶·¸¹º»¼½¾¿"
00664 "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ"
00665 "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß"
00666 "àáâãäåæçèéêëìíîï"
00667 "ðñòóôõö÷øùúûüýþÿ";
00668
00669 void cp_dump(int levelprm, cp_string *str)
00670 {
00671 int rc;
00672 int idx;
00673 char prn[LINELEN];
00674 char lit[CHARS_PER_LINE + 2];
00675 char hc[4];
00676 short line_done = 1;
00677
00678 if (levelprm >= loglevel)
00679 {
00680 rc = str->len;
00681 idx = 0;
00682 lit[CHARS_PER_LINE] = '\0';
00683 while (rc > 0)
00684 {
00685 #ifdef CP_HAS_SNPRINTF
00686 if (line_done) snprintf(prn, LINELEN, "%08X: ", idx);
00687 #else
00688 if (line_done) sprintf(prn, "%08X: ", idx);
00689 #endif
00690 do
00691 {
00692 unsigned char c = str->data[idx];
00693 #ifdef CP_HAS_SNPRINTF
00694 snprintf(hc, 4, "%02X ", (int) c);
00695 #else
00696 sprintf(hc, "%02X ", (int) c);
00697 #endif
00698 #ifdef CP_HAS_STRLCAT
00699 strlcat(prn, hc, LINELEN);
00700 #else
00701 strcat(prn, hc);
00702 #endif
00703 lit[idx % CHARS_PER_LINE] = print_char[c];
00704 } while (--rc > 0 && (++idx % CHARS_PER_LINE != 0));
00705 line_done = (idx % CHARS_PER_LINE) == 0;
00706 if (line_done)
00707 {
00708 printf("%s %s\n", prn, lit);
00709 if (logfile) fprintf(logfile, "%s %s\n", prn, lit);
00710 }
00711 }
00712 if (!line_done)
00713 {
00714 int ldx = idx % CHARS_PER_LINE;
00715 lit[ldx++] = print_char[(int) str->data[idx]];
00716 lit[ldx] = '\0';
00717 while ((++idx % CHARS_PER_LINE) != 0)
00718 #ifdef CP_HAS_STRLCAT
00719 strlcat(prn, " ", LINELEN);
00720 #else
00721 strcat(prn, " ");
00722 #endif
00723 printf("%s %s\n", prn, lit);
00724 if (logfile) fprintf(logfile, "%s %s\n", prn, lit);
00725
00726 }
00727 }
00728 }
00729
00730 void cp_ndump(int levelprm, cp_string *str, size_t len)
00731 {
00732 if (levelprm >= loglevel)
00733 {
00734 int olen = str->len;
00735 if ((unsigned) str->len > len) str->len = len;
00736 cp_dump(levelprm, str);
00737 if (olen != str->len) str->len = olen;
00738 }
00739 }
00740
00741 #if defined(CP_HAS_REGEX_H) || defined(CP_HAS_PCRE)
00742 int log_regex_compilation_error(int rc, char *msg)
00743 {
00744 char *smsg = regex_compilation_error(rc);
00745 cp_error(CP_REGEX_COMPILATION_FAILURE, "%s: %s", msg, smsg);
00746 return rc;
00747 }
00748 #endif
00749