📄 logging.c
字号:
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 += 5; 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': { long sdiff, usdiff; struct timeval x; gettimeofday(&x, NULL); usdiff = x.tv_usec - start_time.tv_usec; sdiff = x.tv_sec - start_time.tv_sec; if (usdiff < 0) { /* borrow 1 sec */ sdiff--; usdiff = 1000000 + usdiff; } len += log_printf("%2d.%06d", sdiff, usdiff); } break;#endif default: CHAROUT('%'); CHAROUT(*s); len+=2; break; } } else { CHAROUT(*s); len++; } s++; } return len;} /* * Simulate 'printf' using log_emitch. Read the buffer to get the * format string and any required args; these are stored in a ulong* buffer: * * +========+======+======+=============+======+======+==========+=======+=== * | format | file | line | flags/level | arg1 | arg2 | ... argn | count | ... * +========+======+======+=============+======+======+==========+=======+=== * * where: * line is the line number of the statement which started the message * file is a pointer to the file name containing the message * flags/level is split: the LS byte is the level number of the message, * the next-LS byte is the bit number of the module bitmask * top 16 bits unused. * format is a pointer to a printf-style format string, * arg1..argn are any arguments implied by 'format' (no args is ok), * count is the number of long int values used, including count itself. * * So: * printf("hello") has a count of 7, * printf("value %d x %d is %d", a, b, c) has a count of 8. * * the arg 'ptr' points at 'format' in the buffer. * * NOTE: Double, float values, precision values (%.8) and variable width fields * are not supported. * * The number of characters printed is returned. */int log_logprint(long msgno, unsigned long *ptr){ int len = 0, lineno, flags; log_id id; char *format, *file; WarnLevel level; #if defined(TARGET) && (!defined(LOGTERM_DEBUGGING) || LOGTERM_DEBUGGING == 0) static char firsttime = 1; if (firsttime) { log_set_log_id(LOG_COMMON, 1); firsttime = 0; }#endif format = (char *)*ptr++; lineno = (int)*ptr++; file = (char *)*ptr++; flags = (int)*ptr++; id = (log_id)((flags >> 8) & 0xFF); level = (WarnLevel)(flags & 0xFF); if ((log_logging_flags[(int)id]) == 0) return 0; if (level < log_min_level) return 0; /* print the per-line information */ if (log_perline) { log_perline = FALSE; log_formatinfo(log_formatstring, lineno, file, id, level, msgno); } /* * This code assumes pointers will fit in an unsigned long value. If * this is not true it WILL BREAK!! */ /* ASSERT(sizeof(unsigned long) >= sizeof(void *), "pointer size problem"); */ 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 = (int)*ptr++; CHAROUT((char)ival); len++; break; } case 'p': /* hexadecimal pointer => ignore longval */ { void *vp = (void*)*ptr++; 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 = (unsigned long)*ptr++; len += log_itoh(fch, luval, width, padzero); } else { unsigned long uval = (unsigned int)*ptr++; len += log_itoh(fch, (unsigned long)uval, width, padzero); } break; case 'i': case 'd': /* decimal */ /* default format: min width */ if (longval) { long lival = (long)*ptr++; len += log_itod(lival, width, padzero, TRUE); } else { int ival = (int)*ptr++; len += log_itod((long)ival, width, padzero, TRUE); } break; case 'u': /* unsigned decimal */ /* default format: min width */ if (longval) { unsigned long lival = (unsigned long)*ptr++; len += log_itod((long)lival, width, padzero, FALSE); } else { unsigned int ival = (unsigned int)*ptr++; len += log_itod((long)ival, width, padzero, FALSE); } break; case 's': /* string => ignore longval */ { char *string = (char *)*ptr++; len += log_ptos(string, width); } break; case '\0': /* * string terminated by '%' character, bodge things * to prepare for default "format++" below */ format--; break; default: /* just display the character */ CHAROUT(*format); len++; break; } } else { CHAROUT(*format); len++; /* if we come to a newline, set log_perline, so we print out the * file and line number when we get the next line. * * Unless, of course, the next line is in this format, in which * case we must print it now... * * [note: we should check %s args for \n too...] */ if (*format == '\n') { if (*(format+1) == '\0') log_perline = TRUE; else { log_perline = FALSE; log_formatinfo(log_formatstring, lineno, file, id, level, msgno); } } else log_perline = FALSE; } format++; /* step over character */ } return len;}/* * Set up save buffer for a new message. Ensure the insert pointer points * into the buffer, and that an intiial empty buffer has a zero in the first * location (the count item) as a terminator. Incrememnt a message number * variable indicating the current message number (the first message will * thus be 1). */void log_setupsave(struct LogSaveBuffer *sb, unsigned long *buffer, long size){ sb->start = buffer; sb->current = buffer; sb->size = size; sb->end = buffer + size; sb->message = 0; log_saveitem(sb, 0); /* end condition for backwards search */}/* * Save a new item (format pointer, arg, count) to the save buffer, wrapping * when the buffer limit is reached. */void log_saveitem(struct LogSaveBuffer *sb, unsigned long item){ *(sb->current) = item; sb->current++; /* implement wrap-around for the permanent save buffer; callers * using their own buffer must implement their own safety checks.. */ if (sb->current == sb->end) { sb->current = sb->start; }}voidLog_logmsginfo(char *file, int line, log_id id){ log_filename = file; log_line = line; log_module = id;}void log_getmsginfo(char **file, int *line, log_id *id){ *file = log_filename; *line = log_line; *id = log_module;}void log_vlog(WarnLevel level, char *format, va_list args){ int len; unsigned long savebuf[16], *ptr; struct LogSaveBuffer tmpbuf; struct LogSaveBuffer *buf; long msgno = 0; /* * if we want a permanent copy of the message, get a copy of * the save location. If not, just use the temporary buffer above. */#if defined(LOGTERM_DEBUGGING) && LOGTERM_DEBUGGING == 1 if (log_logging_options & WL_SAVEMSG) { buf = log_getlogtermbuf(); msgno = buf->message; } else { log_setupsave(&tmpbuf, savebuf, 16); buf = &tmpbuf; }#else log_setupsave(&tmpbuf, savebuf, 16); buf = &tmpbuf;#endif /* * stuff will be saved from here onwards; save this location * so we don't have to calculate it... */ ptr = buf->current; /* * save the info to the save place. We can't call log_vprintf * here because we can't parse 'args' twice :-( */ log_logsave(buf, level, format, args); if (log_logging_options & WL_PRINTMSG) { if (PRE_DEBUG(level)) { len = log_logprint(msgno, ptr); POST_DEBUG(len); } }}/* see logging.h */void log_log(WarnLevel lvl, char *format,...){ va_list args; va_start(args, format); log_vlog(lvl, format, args); va_end(args); return;}/* see logging.h */void log_logwarning(char *format,...){ va_list args; va_start(args, format); log_vlog(WL_WARN, format, args); va_end(args); return;}/* see logging.h */void log_loginfo(char *format,...){ va_list args; va_start(args, format); log_vlog(WL_INFO, format, args); va_end(args); return;}/* see logging.h */void log_logerror(char *format,...){ va_list args; va_start(args, format); log_vlog(WL_ERROR, format, args); va_end(args); return;}/* see logging.h */#undef LogTracevoid LogTrace(char *format,...){ va_list args; if (log_fasttrace) { va_start(args, format); log_vprintf(format, args); va_end(args); } return;}#endif /* DEBUG *//* EOF logging.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -