Subversion Repositories HelenOS-historic

Rev

Rev 1 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2001-2004 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include <putchar.h>
  30. #include <print.h>
  31. #include <synch/spinlock.h>
  32. #include <arch/arg.h>
  33.  
  34.  
  35. static char digits[] = "0123456789abcdef";
  36. static spinlock_t printflock;
  37.  
  38. void print_str(char *str)
  39. {
  40.         int i = 0;
  41.     char c;
  42.    
  43.     while (c = str[i++])
  44.         putchar(c);
  45. }
  46.  
  47.  
  48. /*
  49.  * This is a universal function for printing hexadecimal numbers of fixed
  50.  * width.
  51.  */
  52. void print_fixed_hex(__u32 num, int width)
  53. {
  54.     int i;
  55.    
  56.     for (i = width*8 - 4; i >= 0; i -= 4)
  57.         putchar(digits[(num>>i) & 0xf]);
  58. }
  59.  
  60. /*
  61.  * This is a universal function for printing decimal and hexadecimal numbers.
  62.  * It prints only significant digits.
  63.  */
  64. void print_number(__u32 num, int base)
  65. {
  66.     char d[32+1];       /* this is good enough even for base == 2 */
  67.         int i = 31;
  68.    
  69.     do {
  70.         d[i--] = digits[num % base];
  71.     } while (num /= base);
  72.    
  73.     d[32] = 0; 
  74.     print_str(&d[i + 1]);
  75. }
  76.  
  77. /*
  78.  * This is our function for printing formatted text.
  79.  * It's much simpler than the user-space one.
  80.  * We are greateful for this function.
  81.  */
  82. void printf(char *fmt, ...)
  83. {
  84.     int irqpri, i = 0;
  85.     va_list ap;
  86.     char c;
  87.  
  88.     va_start(ap, fmt);
  89.  
  90.     irqpri = cpu_priority_high();
  91.     spinlock_lock(&printflock);
  92.  
  93.     while (c = fmt[i++]) {
  94.         switch (c) {
  95.  
  96.             /* control character */
  97.             case '%':
  98.                 switch (c = fmt[i++]) {
  99.  
  100.                 /* percentile itself */
  101.                 case '%':
  102.                     break;
  103.  
  104.                 /*
  105.                  * String and character conversions.
  106.                  */
  107.                 case 's':
  108.                     print_str(va_arg(ap, char_ptr));
  109.                     goto loop;
  110.  
  111.                 case 'c':
  112.                     c = va_arg(ap, char);
  113.                     break;
  114.  
  115.                 /*
  116.                          * Hexadecimal conversions with fixed width.
  117.                          */
  118.                 case 'L':
  119.                     print_str("0x");
  120.                 case 'l':
  121.                         print_fixed_hex(va_arg(ap, __native), INT32);
  122.                     goto loop;
  123.  
  124.                 case 'W':
  125.                     print_str("0x");
  126.                 case 'w':
  127.                         print_fixed_hex(va_arg(ap, __native), INT16);
  128.                     goto loop;
  129.  
  130.                 case 'B':
  131.                     print_str("0x");
  132.                 case 'b':
  133.                         print_fixed_hex(va_arg(ap, __native), INT8);
  134.                     goto loop;
  135.  
  136.                 /*
  137.                          * Decimal and hexadecimal conversions.
  138.                          */
  139.                 case 'd':
  140.                         print_number(va_arg(ap, __native), 10);
  141.                     goto loop;
  142.  
  143.                 case 'X':
  144.                             print_str("0x");
  145.                 case 'x':
  146.                         print_number(va_arg(ap, __native), 16);
  147.                     goto loop;
  148.        
  149.                 /*
  150.                  * Bad formatting.
  151.                  */
  152.                 default:
  153.                     goto out;
  154.                 }
  155.  
  156.             default: putchar(c);
  157.         }
  158.    
  159. loop:
  160.         ;
  161.     }
  162.  
  163. out:
  164.     spinlock_unlock(&printflock);
  165.     cpu_priority_restore(irqpri);
  166.    
  167.     va_end(ap);
  168. }
  169.