Subversion Repositories HelenOS-historic

Compare Revisions

Problem with comparison.

Ignore whitespace Rev HEAD → Rev 1

/SPARTAN/trunk/src/debug/print.c
0,0 → 1,160
/*
* Copyright (C) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <putchar.h>
#include <print.h>
#include <synch/spinlock.h>
 
static char digits[] = "0123456789abcdef";
static spinlock_t printflock;
 
void print_str(char *str)
{
int i = 0;
char c;
while (c = str[i++])
putchar(c);
}
 
 
/*
* This is a universal function for printing hexadecimal numbers of fixed
* width.
*/
void print_fixed_hex(__u32 num, int width)
{
int i;
for (i = width*8 - 4; i >= 0; i -= 4)
putchar(digits[(num>>i) & 0xf]);
}
 
/*
* This is a universal function for printing decimal and hexadecimal numbers.
* It prints only significant digits.
*/
void print_number(__u32 num, int base)
{
char d[32+1]; /* this is good enough even for base == 2 */
int i = 31;
do {
d[i--] = digits[num % base];
} while (num /= base);
d[32] = 0;
print_str(&d[i + 1]);
}
 
/*
* This is our function for printing formatted text.
* It's much simpler than the user-space one.
* We are greateful for this function.
*/
void printf(char *fmt, ...)
{
int irqpri, i = 0, pos = 0;
char c;
 
irqpri = cpu_priority_high();
spinlock_lock(&printflock);
while (c = fmt[i++]) {
switch (c) {
 
/* control character */
case '%':
switch (c = fmt[i++]) {
 
/* percentile itself */
case '%':
break;
 
/*
* String and character conversions.
*/
case 's':
print_str((char *) *(((__address *) &fmt + (++pos))));
goto loop;
 
case 'c':
c = *((char *) ((__address *)(&fmt + (++pos))));
break;
 
/*
* Hexadecimal conversions with fixed width.
*/
case 'L':
print_str("0x");
case 'l':
print_fixed_hex(*((__address *)(&fmt + (++pos))),INT32);
goto loop;
 
case 'W':
print_str("0x");
case 'w':
print_fixed_hex(*((__address *)(&fmt + (++pos))),INT16);
goto loop;
 
case 'B':
print_str("0x");
case 'b':
print_fixed_hex(*((__address *)(&fmt + (++pos))),INT8);
goto loop;
 
/*
* Decimal and hexadecimal conversions.
*/
case 'd':
print_number(*((__address *)(&fmt + (++pos))), 10);
goto loop;
 
case 'X':
print_str("0x");
case 'x':
print_number(*((__address *)(&fmt + (++pos))), 16);
goto loop;
/*
* Bad formatting.
*/
default:
goto out;
}
 
default: putchar(c);
}
loop:
;
}
 
out:
spinlock_unlock(&printflock);
cpu_priority_restore(irqpri);
}