⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logging.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
        }        while ((fch >= '0') && (fch <= '9'))        {            *width = (((*width) * 10) + (fch - '0'));            fch = *(++(*format));        }    }    if (fch == 'l')    {        /* skip 'l' in "%lx", etc. */        *longval = TRUE;        fch = *(++(*format));    }    return fch;}/* * Convert the long value ival to text, writing the result character * by character using the 'CHAROUT' macro in hexadecimal.  * * fch is used to specify one of the three variants used: 'p' for * the pointer type (0x00224AFDB etc) 'X' for hex numbers with leading * 0x and capital letter A-F, 'x' for hex numbers with no leading 0x * and lower-case a-f. * * width is the field width, which may be exceeded if representation * of the value demands, pad is TRUE if the value should be padded to * to the left up to the width * */static int log_itoh(char fch, unsigned long uval, int width, int padzero){    int count, loop;    int len = 0, mark = FALSE;    const char *hextab;    char buffer[12];  /* stack space used to hold number */    if (fch == 'X' || fch == 'p')    {        hextab = hextab1;        if (fch == 'p')            mark = TRUE;    }    else    {        hextab = hextab2;    }    /*     * Read each nibble from high to low; unless it's zero copy the     * hex character equivalent into the buffer. Note we start from     * bit (n-4) where (n) is the number of bits in the word, as     * loop is the base bit number (i.e. the nibble is from the bit     * at 'loop' to the bit at 'loop+3'.     */    count = 0;    for (loop = (sizeof(long) * 8) - 4; loop >= 0; loop -= 4)    {        int nibble = (uval >> loop) & 0xF;        if (nibble != 0 || count != 0)        {            buffer[count++] = hextab[nibble];        }    }    if (count == 0)        buffer[count++] = '0';    if (width != 0)      {        width -= count + (mark? 2: 0);        if (padzero)          {            if (mark)              {                CHAROUT('0');                CHAROUT('x');                len += 2;              }            for (; (width > 0); width--)              {                CHAROUT('0');                len++;              }          }        else          {            for (; (width > 0); width--)              {                CHAROUT(' ');                len++;              }            if (mark)              {                CHAROUT('0');                CHAROUT('x');                len += 2;              }          }      }    else if (mark)      {        CHAROUT('0');        CHAROUT('x');        len += 2;      }        for (loop = 0; loop < count; loop++)    {        CHAROUT(buffer[loop]);        len++;    }    return len;}/* * Convert the long value ival to text, writing the result character * by character using the 'CHAROUT' macro in hexadecimal.  * * fch is used to specify one of the three variants used: 'p' for * the pointer type (0x00224AFDB etc) 'X' for hex numbers with leading * 0x and capital letter A-F, 'x' for hex numbers with no leading 0x * and lower-case a-f. * * width is the field width, which may be exceeded if representation * of the value demands, pad is TRUE if the value should be padded to * to the left up to the width * */static int buf_itoh(char *buf, unsigned long uval, int width, int padzero){    int count, loop;    int len = 0;    char buffer[12];  /* stack space used to hold number */    count = 0;    for (loop = (sizeof(long) * 8) - 4; loop >= 0; loop -= 4)    {        int nibble = (uval >> loop) & 0xF;        if (nibble != 0 || count != 0)        {            buffer[count++] = hextab2[nibble];        }    }    if (count == 0)        buffer[count++] = '0';    if (width != 0)    {        width -= count;                for (; (width > 0); width--)        {            *buf++ = (padzero)?'0':' ';            len++;        }    }        for (loop = 0; loop < count; loop++)    {        *buf++ = (buffer[loop]);        len++;    }    return len;}/* * Convert the long value ival to text, writing the result character * by character using the 'CHAROUT' macro in decimal.  * * width is the field width, which may be exceeded if representation * of the value demands, padzero is TRUE if the value should be padded to * to the left up to the width, sign is TRUE if the value should be * considered to be a signed number. * * note: the sign char is not counted in the field width [BUG] */static int log_itod(long ival, int width, int padzero, int sign){    int count;    int len = 0;    int writeminus = FALSE;    char buffer[12];  /* stack space used to hold number */    if (sign && (ival < 0))    {        ival = -ival;        writeminus = TRUE;    }    /*     * The simplest method of displaying numbers is to     * provide a small recursive routine. However, to reduce     * stack usage the following non-recursive solution is     * used.     */    /*     * Place the conversion into the buffer in     * reverse order:     */    count = 0;    while (ival != 0)    {        buffer[count++] = (char)('0' + ((unsigned long)ival % 10));        ival = ((unsigned long)ival / 10);    }    if (count == 0)        buffer[count++] = '0';    /*     * Check if we are placing the data in a fixed      * width field, and write the minus in the right     * place relative to the padding.     */    if (width != 0)    {        width -= count + (writeminus ? 1 : 0);        if (padzero)        {            if (writeminus)            {                    CHAROUT('-');                len++;            }            for (; (width > 0); width--)            {                CHAROUT('0');                len++;            }        }        else        {            for (; (width > 0); width--)            {                CHAROUT(' ');                len++;            }                            if (writeminus)            {                    CHAROUT('-');                len++;            }        }    }    else if (writeminus)    {            CHAROUT('-');        len++;    }    /* 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, bodge things                     * to 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 * * where (line,file) are compile-time optional. * * 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!!     */    /* ASSERT(sizeof(unsigned long) >= sizeof(void *), "pointer size problem"); */    sb->message++;    log_saveitem(sb, (unsigned long)format);    log_getmsginfo(&file, &line, &id);    log_saveitem(sb, (unsigned long)line);    log_saveitem(sb, (unsigned long)file);    log_saveitem(sb, level | (id & 0xff) << 8);        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':

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -