Fix gcc inline assembler operand constraints for syscall -- as pushl modifies %esp...
[pintos-anon] / src / lib / user / console.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <syscall.h>
4 #include <syscall-nr.h>
5
6 /* The standard vprintf() function,
7    which is like printf() but uses a va_list. */
8 int
9 vprintf (const char *format, va_list args) 
10 {
11   return vhprintf (STDOUT_FILENO, format, args);
12 }
13
14 /* Like printf(), but writes output to the given HANDLE. */
15 int
16 hprintf (int handle, const char *format, ...) 
17 {
18   va_list args;
19   int retval;
20
21   va_start (args, format);
22   retval = vhprintf (handle, format, args);
23   va_end (args);
24
25   return retval;
26 }
27
28 /* Writes string S to the console, followed by a new-line
29    character. */
30 int
31 puts (const char *s) 
32 {
33   write (STDOUT_FILENO, s, strlen (s));
34   putchar ('\n');
35
36   return 0;
37 }
38
39 /* Writes C to the console. */
40 int
41 putchar (int c) 
42 {
43   char c2 = c;
44   write (STDOUT_FILENO, &c2, 1);
45   return c;
46 }
47 \f
48 /* Auxiliary data for vhprintf_helper(). */
49 struct vhprintf_aux 
50   {
51     char buf[64];       /* Character buffer. */
52     char *p;            /* Current position in buffer. */
53     int char_cnt;       /* Total characters written so far. */
54     int handle;         /* Output file handle. */
55   };
56
57 static void add_char (char, void *);
58 static void flush (struct vhprintf_aux *);
59
60 /* Formats the printf() format specification FORMAT with
61    arguments given in ARGS and writes the output to the given
62    HANDLE. */
63 int
64 vhprintf (int handle, const char *format, va_list args) 
65 {
66   struct vhprintf_aux aux;
67   aux.p = aux.buf;
68   aux.char_cnt = 0;
69   aux.handle = handle;
70   __vprintf (format, args, add_char, &aux);
71   flush (&aux);
72   return aux.char_cnt;
73 }
74
75 /* Adds C to the buffer in AUX, flushing it if the buffer fills
76    up. */
77 static void
78 add_char (char c, void *aux_) 
79 {
80   struct vhprintf_aux *aux = aux_;
81   *aux->p++ = c;
82   if (aux->p >= aux->buf + sizeof aux->buf)
83     flush (aux);
84   aux->char_cnt++;
85 }
86
87 /* Flushes the buffer in AUX. */
88 static void
89 flush (struct vhprintf_aux *aux)
90 {
91   if (aux->p > aux->buf)
92     write (aux->handle, aux->buf, aux->p - aux->buf);
93   aux->p = aux->buf;
94 }