Subversion Repositories HelenOS-historic

Rev

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.  
  33. static char digits[] = "0123456789abcdef";
  34. static spinlock_t printflock;
  35.  
  36. void print_str(char *str)
  37. {
  38.         int i = 0;
  39.     char c;
  40.    
  41.     while (c = str[i++])
  42.         putchar(c);
  43. }
  44.  
  45.  
  46. /*
  47.  * This is a universal function for printing hexadecimal numbers of fixed
  48.  * width.
  49.  */
  50. void print_fixed_hex(__u32 num, int width)
  51. {
  52.     int i;
  53.    
  54.     for (i = width*8 - 4; i >= 0; i -= 4)
  55.         putchar(digits[(num>>i) & 0xf]);
  56. }
  57.  
  58. /*
  59.  * This is a universal function for printing decimal and hexadecimal numbers.
  60.  * It prints only significant digits.
  61.  */
  62. void print_number(__u32 num, int base)
  63. {
  64.     char d[32+1];       /* this is good enough even for base == 2 */
  65.         int i = 31;
  66.    
  67.     do {
  68.         d[i--] = digits[num % base];
  69.     } while (num /= base);
  70.    
  71.     d[32] = 0; 
  72.     print_str(&d[i + 1]);
  73. }
  74.  
  75. /*
  76.  * This is our function for printing formatted text.
  77.  * It's much simpler than the user-space one.
  78.  * We are greateful for this function.
  79.  */
  80. void printf(char *fmt, ...)
  81. {
  82.     int irqpri, i = 0, pos = 0;
  83.     char c;
  84.  
  85.     irqpri = cpu_priority_high();
  86.     spinlock_lock(&printflock);
  87.     while (c = fmt[i++]) {
  88.         switch (c) {
  89.  
  90.             /* control character */
  91.             case '%':
  92.                 switch (c = fmt[i++]) {
  93.  
  94.                 /* percentile itself */
  95.                 case '%':
  96.                     break;
  97.  
  98.                 /*
  99.                  * String and character conversions.
  100.                  */
  101.                 case 's':
  102.                     print_str((char *) *(((__address *) &fmt + (++pos))));
  103.                     goto loop;
  104.  
  105.                 case 'c':
  106.                     c = *((char *) ((__address *)(&fmt + (++pos))));
  107.                     break;
  108.  
  109.                 /*
  110.                          * Hexadecimal conversions with fixed width.
  111.                          */
  112.                 case 'L':
  113.                     print_str("0x");
  114.                 case 'l':
  115.                         print_fixed_hex(*((__address *)(&fmt + (++pos))),INT32);
  116.                     goto loop;
  117.  
  118.                 case 'W':
  119.                     print_str("0x");
  120.                 case 'w':
  121.                         print_fixed_hex(*((__address *)(&fmt + (++pos))),INT16);
  122.                     goto loop;
  123.  
  124.                 case 'B':
  125.                     print_str("0x");
  126.                 case 'b':
  127.                         print_fixed_hex(*((__address *)(&fmt + (++pos))),INT8);
  128.                     goto loop;
  129.  
  130.                 /*
  131.                          * Decimal and hexadecimal conversions.
  132.                          */
  133.                 case 'd':
  134.                         print_number(*((__address *)(&fmt + (++pos))), 10);
  135.                     goto loop;
  136.  
  137.                 case 'X':
  138.                             print_str("0x");
  139.                 case 'x':
  140.                         print_number(*((__address *)(&fmt + (++pos))), 16);
  141.                     goto loop;
  142.        
  143.                 /*
  144.                  * Bad formatting.
  145.                  */
  146.                 default:
  147.                     goto out;
  148.                 }
  149.  
  150.             default: putchar(c);
  151.         }
  152.    
  153. loop:
  154.         ;
  155.     }
  156.  
  157. out:
  158.     spinlock_unlock(&printflock);
  159.     cpu_priority_restore(irqpri);
  160. }
  161.