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