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
00038 #include "fastlib/base/common.h"
00039
00040 #include <stdarg.h>
00041 #include <unistd.h>
00042
00043 int segfault_on_abort = 0;
00044 int abort_on_nonfatal = 0;
00045 int pause_on_nonfatal = 0;
00046 int print_notify_locs = 0;
00047
00048 char fl_msg_marker[] = {'X', '!', '*', '.'};
00049 const char *fl_msg_color[] =
00050 {ANSI_HRED, ANSI_YELLOW, ANSI_HGREEN, ANSI_HBLUE};
00051
00052 void fl_abort(void)
00053 {
00054 if (segfault_on_abort) {
00055 fflush(NULL);
00056 *(int*)NULL = 0;
00057 }
00058 abort();
00059 }
00060
00061 void fl_pause(void)
00062 {
00063 if (isatty(0)) {
00064 char c;
00065
00066 fprintf(stderr, ANSI_HBLACK"Press Return to continue..."ANSI_CLEAR);
00067 fflush(stderr);
00068
00069 while ((c = getchar()) != EOF && c != '\n');
00070 }
00071 }
00072
00073 void fl_print_msg_header(char marker, const char *color)
00074 {
00075 fprintf(stderr, "%s[%c]%s ", color, marker, ANSI_CLEAR);
00076 }
00077
00078 void fl_print_msg_loc(const char *file, const char *func, int line)
00079 {
00080 const char *prev = file;
00081 const char *last = file;
00082
00083
00084 while ((file = strchr(last, '/'))) {
00085 prev = last;
00086 last = file + 1;
00087 }
00088
00089 fprintf(stderr, "%s:%s:%d: ", prev, func, line);
00090 }
00091
00092 void fl_print_fatal_msg(const char *file, const char *func, int line,
00093 const char *format, ...)
00094 {
00095 va_list vl;
00096
00097 fl_print_msg_header(fl_msg_marker[FL_MSG_FATAL],
00098 fl_msg_color[FL_MSG_FATAL]);
00099 fl_print_msg_loc(file, func, line);
00100
00101 va_start(vl, format);
00102 vfprintf(stderr, format, vl);
00103 va_end(vl);
00104
00105 fprintf(stderr, "\n");
00106
00107 fl_abort();
00108 }
00109
00110 void fl_print_msg(const char *file, const char *func, int line,
00111 fl_msg_t msg_type, const char *format, ...)
00112 {
00113 va_list vl;
00114
00115 fl_print_msg_header(fl_msg_marker[msg_type], fl_msg_color[msg_type]);
00116 if (msg_type < FL_MSG_NOTIFY_STAR || print_notify_locs) {
00117 fl_print_msg_loc(file, func, line);
00118 }
00119
00120 va_start(vl, format);
00121 vfprintf(stderr, format, vl);
00122 va_end(vl);
00123
00124 fprintf(stderr, "\n");
00125
00126 if (msg_type < FL_MSG_NOTIFY_STAR) {
00127 if (msg_type == FL_MSG_FATAL || abort_on_nonfatal) {
00128 fl_abort();
00129 } else if (pause_on_nonfatal) {
00130 fl_pause();
00131 }
00132 }
00133 }
00134
00135 void fl_print_progress(const char *desc, int prec)
00136 {
00137 const int BAR_LEN = 50;
00138 static int prev_prec = -1;
00139 static const char *prev_desc = NULL;
00140
00141 if (isatty(0)) {
00142 if (unlikely(prec != prev_prec || desc != prev_desc)) {
00143 char buf[BAR_LEN + 1];
00144 int pos = prec * BAR_LEN / 100;
00145 int i = 0;
00146
00147 pos = unlikely(pos > BAR_LEN) ? BAR_LEN : unlikely(pos < 0) ? 0 : pos;
00148
00149 for (; i < pos; ++i) {
00150 buf[i] = '#';
00151 }
00152 for (; i < BAR_LEN; ++i) {
00153 buf[i] = '.';
00154 }
00155 buf[i] = '\0';
00156
00157 fprintf(stderr, "\r"ANSI_BLUE"[%s] %d%% %s"ANSI_CLEAR"\r",
00158 buf, prec, desc);
00159
00160 prev_prec = prec;
00161 prev_desc = desc;
00162 }
00163 }
00164 }
00165
00166 void hex_to_stream(FILE *stream, const char *src, const char *ok_char)
00167 {
00168 char c;
00169
00170 while ((c = *src++)) {
00171 if (isalnum(c) || strchr(ok_char, c)) {
00172 putc(c, stream);
00173 } else {
00174 fprintf(stream, "%%%02X", (unsigned)c);
00175 }
00176 }
00177 }
00178
00179 char *hex_to_string(char *dest, const char *src, const char *ok_char)
00180 {
00181 char c;
00182
00183 while ((c = *src++)) {
00184 if (isalnum(c) || strchr(ok_char, c)) {
00185 *dest++ = c;
00186 } else {
00187 sprintf(dest, "%%%02X", (unsigned)c);
00188 dest += 3;
00189 }
00190 }
00191
00192 *dest = '\0';
00193 return dest;
00194 }
00195
00196 char *unhex_in_place(char *str)
00197 {
00198 char *dest = strchr(str, '%');
00199
00200 if (dest) {
00201 str = dest;
00202 while (*str) {
00203 if (*str == '%' && isxdigit(str[1]) && isxdigit(str[2])) {
00204 sscanf(str + 1, "%2hhx", dest++);
00205 str += 3;
00206 } else {
00207 *dest++ = *str++;
00208 }
00209 }
00210
00211 *dest = '\0';
00212 return dest;
00213 } else {
00214 return str + strlen(str);
00215 }
00216 }