📄 logging.c
字号:
/* then display the buffer in reverse order */ for (; (count != 0); count--) { CHAROUT(buffer[count - 1]); len++; } return len;}/* * Convert the zero-terminated string stored in memory at address 'string' * to characters passed to CHAROUT. If width is non-zero, and is larger * than the string length, then pad characters will be used to make up the * string to this length, padding on the right. If the pointer value is NULL * the characters "(nil)" will be written instead. */static int log_ptos(char *string, int width){ int len = 0; if (string != NULL) { while (*string) { /* * NOTE: We do not use "*string++" as the macro * parameter, since we do not know how many times * the parameter may be expanded within the macro. */ CHAROUT(*string); len++; string++; } if (width != 0) { width -= len; for (; (width > 0); width--) { CHAROUT(' '); len++; } } } else { CHAROUT('('); CHAROUT('n'); CHAROUT('i'); CHAROUT('l'); CHAROUT(')'); len += 5; } return len;}/* * Simulate 'printf' using the CHAROUT macro. Read a format string to interpret * the n args following (n >= 0) as pointers, integers or characters (as ints). * NOTE: Double, float values, precision values (%.8) and variable width fields * are not supported. * * The number of characters printed is returned. */int log_printf(char *format, ...){ va_list args; int l; va_start(args, format); l = log_vprintf(format, args); va_end(args); return l;}static int log_vprintf(char *format, va_list args){ int len = 0; while ((format != NULL) && (*format != '\0')) { if (*format == '%') { char fch; /* get format character (skipping '%') */ int width = 0; /* No field width by default */ int padzero = FALSE; /* By default we pad with spaces */ int longval = FALSE; /* seen 'ld' etc? */ fch = log_readformat(&format, &width, &padzero, &longval); switch (fch) { case 'c': /* char => ignore longval */ { int ival = va_arg(args, int); CHAROUT((char)ival); len++; break; } case 'p': /* hexadecimal pointer => ignore longval */ { void *vp = va_arg(args, void *); if (width == 0) { /* default format: 8 digits wide, leading "0x", zero padded */ width = 8; padzero = TRUE; } len += log_itoh(fch, (unsigned long)vp, width, padzero); break; } case 'X': case 'x': /* hexadecimal */ /* default format: min width */ if (longval) { unsigned long luval = va_arg(args, unsigned long); len += log_itoh(fch, luval, width, padzero); } else { unsigned int uval = va_arg(args, unsigned int); len += log_itoh(fch, (unsigned long)uval, width, padzero); } break; case 'i': case 'd': /* decimal */ /* default format: min width */ if (longval) { long lival = va_arg(args, long); len += log_itod(lival, width, padzero, TRUE); } else { int ival = va_arg(args, int); len += log_itod((long)ival, width, padzero, TRUE); } break; case 'u': /* unsigned decimal */ /* default format: min width */ if (longval) { unsigned long lival = va_arg(args, unsigned long); len += log_itod((long)lival, width, padzero, FALSE); } else { unsigned int ival = va_arg(args, unsigned int); len += log_itod((long)ival, width, padzero, FALSE); } break; case 's': /* string => ignore longval */ { char *string = va_arg(args, char *); len += log_ptos(string, width); } break; case '\0': /* * string terminated by '%' character, * prepare for default "format++" below */ format--; break; default: /* just display the character */ CHAROUT(*format); len++; break; } } else { CHAROUT(*format); len++; } format++; } return len;}/* * Routine to return the bit number of the single bit set in 'x'. * * Multiply the value 'x' by the 'magic number' 0x450FBAF * extracting the most significant 6 bits of the 32 bit * answer. The result is a unique value. * take this unique value and return it's bit postition via a[]. * * Algorithm courtesy D. Seal. */int __rt_bitnumber(unsigned long x){ static unsigned char a[64] = { 0, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10, 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27, 15, 31, 11, 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0, 20, 26, 30, 0, 0, 0, 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0 }; if (x == 0) return 0xff; x *= 0x11; /* multiply by 17 -> total factor 0x11 */ x *= 0x41; /* multiply by 65 -> total factor 0x451 */ x *= 0xffff; /* multiply by 65535 -> total factor 0x450FBAF */ return (int)(a[x >> 26]);}/* * Save the current format and args in the message save buffer. * The format must be parsed to determine the number and approximate * types of the args, then these args must be saved in the buffer. * The data: * * ulong format, line, file, flags, <args>, ulong count * * should be appended to the message buffer, starting at savebufinsert, * when this routine exits. Args are all converted to unsigned long * type, as this is the type of the buffer. Note that the count * value includes itself and the format, so it's minimum value is 2. * A count of zero is used in the buffer to indicate start-of-data. */static void log_logsave(struct LogSaveBuffer *sb, WarnLevel level, char *format, va_list args){ int argcount = 0; char *file; int line; log_id id; /* * This code assumes pointers will fit in an unsigned long value. If * this is not true it WILL BREAK!! */ sb->message++; log_getmsginfo(&file, &line, &id); log_saveitem(sb, (unsigned long)format); argcount++; log_saveitem(sb, (unsigned long)line); argcount++; log_saveitem(sb, (unsigned long)file); argcount++; log_saveitem(sb, (level & 0xFFFF) | (id & 0xFFFF) << 16); argcount++; while ((format != NULL) && (*format != '\0')) { if (*format == '%') { char fch; /* get format character (skipping '%') */ int ival; /* holder for integer arguments */ char *string; /* holder for string arguments */ void *vp; int longval = FALSE; /* seen 'ld' etc? */ /* these aren't needed, except by log_readformat() ... sigh */ int width = 0; int padzero = FALSE;/* seen '04' etc? */ fch = log_readformat(&format, &width, &padzero, &longval); switch (fch) { case 'c': /* char */ ival = va_arg(args, int); log_saveitem(sb, (unsigned long)ival); argcount++; break; case 'p': /* hexadecimal pointer */ vp = va_arg(args, void *); log_saveitem(sb, (unsigned long)vp); argcount++; break; case 'd': case 'u': case 'i': case 'x': case 'X': if (longval) { unsigned long uval = va_arg(args, unsigned long); log_saveitem(sb, uval); argcount++; } else { unsigned int uval = va_arg(args, unsigned int); log_saveitem(sb, (unsigned long)uval); argcount++; } break; case 's': /* string */ string = va_arg(args, char *); log_saveitem(sb, (unsigned long)string); argcount++; break; case '\0': /* * string terminated by '%' character, bodge things * to prepare for default "format++" below */ format--; break; default: break; } } format++; } /* * Save the count of items in this 'entry' -- format + (f,l) + flags + n args + count * However, we must also save whether this item completes a line of text. * This information is used to manipulate message number counts etc. */ argcount++; /* the one we're just about to do. */ if (format != NULL && *(format-1) == '\n') log_saveitem(sb, (unsigned long)argcount | 0xFF00L); else log_saveitem(sb, (unsigned long)argcount); return;}/* * Interpret strings with %x for various x as format strings * for the per-line trace info. * * x is one of: * w -- warn level -> "I", "W", "E" for Info -> Error * M -- module no * m -- module name, by calling log_tracename() on the bits arg * l -- line number in 4 chars * f -- file name (may be null if not compiled DEBUG_FILE_TOO) * n -- message number in 4 chars * % -- the % character * * sequences other than these are printed verbatim. */intlog_formatinfo(char *str, int lineno, char *file, log_id id, WarnLevel level, long msgno){ char *s = str; int len = 0; while(*s) { if (*s == '%') { s++; switch(*s) { case '%': CHAROUT('%'); len++; break; case 'w': switch(level) { case WL_INFO: CHAROUT('I'); len++; break; case WL_WARN: CHAROUT('W'); len++; break; case WL_ERROR: CHAROUT('E'); len++; break; default: CHAROUT('%'); CHAROUT('w'); len+=2; break; } break; case 'm': if (id == 0) len += log_printf("%8s", "(unset)"); else len += log_printf("%8s", log_tracename(id)); break; case 'l': len += log_printf("%4d", lineno); break; case 'M': len += log_printf("%2d", id); break; case 'f': if (file == NULL) len += log_printf("%15s", "(unset)"); else len += log_printf("%15s", file); break; case 'n': len += log_printf("%4d", msgno); break;#if !defined(TARGET) && !defined(COMPILING_ON_WINDOWS) case 't':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -