X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Flib.c;h=17b0a8086e174a65595bcc11c879fe531a69ae15;hb=04a688940693c2286530386c05f2c8465da1a6a9;hp=7112ba20cc50a5525104b112d5f90c1b89d6d2d0;hpb=5256479f5a331d6baa28726f8b656ada19f99fd5;p=pintos-anon diff --git a/src/lib/lib.c b/src/lib/lib.c index 7112ba2..17b0a80 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -3,6 +3,7 @@ #include #include #include "debug.h" +#include "interrupt.h" #include "lib.h" #include "serial.h" #include "vga.h" @@ -113,13 +114,13 @@ strchr (const char *string, int c_) return NULL; else string++; } - + static void vprintf_core (const char *format, va_list args, void (*output) (char, void *), void *aux); static void -output_console (char ch, void *aux __attribute__ ((unused))) +vprintk_helper (char ch, void *aux __attribute__ ((unused))) { vga_putc (ch); serial_outb (ch); @@ -128,7 +129,9 @@ output_console (char ch, void *aux __attribute__ ((unused))) void vprintk (const char *format, va_list args) { - vprintf_core (format, args, output_console, NULL); + enum if_level old_level = intr_disable (); + vprintf_core (format, args, vprintk_helper, NULL); + intr_set_level (old_level); } void @@ -141,6 +144,53 @@ printk (const char *format, ...) va_end (args); } +struct vsnprintf_aux + { + char *p; + int length; + int max_length; + }; + +static void +vsnprintf_helper (char ch, void *aux_) +{ + struct vsnprintf_aux *aux = aux_; + + if (aux->length++ < aux->max_length) + *aux->p++ = ch; +} + +int +vsnprintf (char *buffer, size_t buf_size, + const char *format, va_list args) +{ + struct vsnprintf_aux aux; + aux.p = buffer; + aux.length = 0; + aux.max_length = buf_size > 0 ? buf_size - 1 : 0; + + vprintf_core (format, args, vsnprintf_helper, &aux); + + if (buf_size > 0) + *aux.p = '\0'; + + return aux.length; +} + +int +snprintf (char *buffer, size_t buf_size, + const char *format, ...) +{ + va_list args; + int retval; + + va_start (args, format); + retval = vsnprintf (buffer, buf_size, format, args); + va_end (args); + + return retval; +} + /* printf() and friends internals. You do not need to understand this code. */ @@ -152,7 +202,8 @@ struct printf_conversion PLUS = 1 << 1, SPACE = 1 << 2, POUND = 1 << 3, - ZERO = 1 << 4 + ZERO = 1 << 4, + GROUP = 1 << 5 } flags; @@ -174,7 +225,8 @@ struct printf_conversion }; static const char * -parse_conversion (const char *format, struct printf_conversion *c, va_list *args) +parse_conversion (const char *format, struct printf_conversion *c, + va_list *args) { /* Parse flag characters. */ c->flags = 0; @@ -197,6 +249,9 @@ parse_conversion (const char *format, struct printf_conversion *c, va_list *args case '0': c->flags |= ZERO; break; + case '\'': + c->flags |= GROUP; + break; default: format--; goto not_a_flag; @@ -314,29 +369,36 @@ printf_integer (uintmax_t value, bool negative, const char *digits, char buf[64], *cp; int base; const char *base_name; - int pad_cnt; + int pad_cnt, group_cnt; base = strlen (digits); /* Accumulate digits into buffer. - This algorithm produces digits in reverse order, so we count - backward from the end of the array. */ + This algorithm produces digits in reverse order, so later we + will output the buffer's content in reverse. This is also + the reason that later we append zeros and the sign. */ cp = buf; + group_cnt = 0; while (value > 0) { + if ((c->flags & GROUP) && group_cnt++ == 3) + { + *cp++ = ','; + group_cnt = 0; + } *cp++ = digits[value % base]; value /= base; } - /* Prepend enough zeros to match precision. + /* Append enough zeros to match precision. If precision is 0, then a value of zero is rendered as a null string. Otherwise at least one digit is presented. */ if (c->precision < 0) c->precision = 1; - while (cp - buf < c->precision && cp - buf > (int) sizeof buf - 8) + while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8) *cp++ = '0'; - /* Prepend sign. */ + /* Append sign. */ if (c->flags & PLUS) *cp++ = negative ? '-' : '+'; else if (c->flags & SPACE) @@ -586,3 +648,33 @@ vprintf_core (const char *format, va_list args, } } } + +void +hex_dump (const void *buffer, size_t size) +{ + const size_t n_per_line = 16; + const uint8_t *p = buffer; + size_t ofs = 0; + + while (size > 0) + { + size_t n, i; + + printk ("%08zx", ofs); + n = size >= n_per_line ? n_per_line : size; + for (i = 0; i < n; i++) + printk ("%c%02x", i == n / 2 ? '-' : ' ', (unsigned) p[i]); + for (; i < n_per_line; i++) + printk (" "); + printk (" |"); + for (i = 0; i < n; i++) + printk ("%c", isprint (p[i]) ? p[i] : '.'); + for (; i < n_per_line; i++) + printk (" "); + printk ("|\n"); + + p += n; + ofs += n; + size -= n; + } +}