]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/loader/server/src/log.cc
da49d1e96f6e58181220f4728a93cd057be5b01c
[l4.git] / l4 / pkg / loader / server / src / log.cc
1 /*
2  * (c) 2008-2009 Technische Universität Dresden
3  * This file is part of TUD:OS and distributed under the terms of the
4  * GNU General Public License 2.
5  * Please see the COPYING-GPL-2 file for details.
6  */
7 #include <l4/re/log>
8 #include <l4/re/log-sys.h>
9 #include <l4/re/protocols>
10 #include <l4/sys/kdebug.h>
11 #include <l4/cxx/minmax>
12
13 #include "log.h"
14 #include "global.h"
15 #include "obj_reg.h"
16
17 #include <cstdio>
18 #include <unistd.h>
19
20 static Ldr::Log *last_log = 0;
21
22 static void my_outnstring(char const *s, unsigned long len)
23 {
24   write(1, s, len);
25 }
26
27 static void mycpy(char **buf, int *rem, char const *s, int l)
28 {
29   int o = cxx::min(*rem, l);
30   memcpy(*buf, s, o);
31   *rem -= o;
32   *buf += o;
33 }
34
35 static char msgbuf[4096];
36
37 int
38 Ldr::Log::dispatch(l4_umword_t, L4::Ipc_iostream &ios)
39 {
40   l4_msgtag_t tag;
41   ios >> tag;
42
43   if (tag.label() != L4_PROTO_LOG)
44     return -L4_EBADPROTO;
45
46   L4::Opcode op;
47
48   // get opcode out of the message stream
49   ios >> op;
50
51   // we only have one opcode
52   if (op != L4Re::Log_::Print)
53     return -L4_ENOSYS;
54
55   char *msg = Glbl::log_buffer;
56   unsigned long len_msg = sizeof(Glbl::log_buffer);
57
58   ios >> L4::ipc_buf_cp_in(msg, len_msg);
59
60   int rem = sizeof(msgbuf);
61   while (len_msg > 0 && msg[0])
62     {
63       char *obuf = msgbuf;
64 #if 1
65       if (color())
66         {
67           int n = snprintf(obuf, rem, "\033[%s3%dm",
68               (color() & 8) ? "01;" : "", (color() & 7));
69           obuf = obuf + n;
70           rem -= n;
71         }
72       else
73         mycpy(&obuf, &rem, "\033[0m", 4);
74 #endif
75       if (last_log != this)
76         {
77           if (last_log != 0)
78             my_outnstring("\n", 1);
79
80           mycpy(&obuf, &rem, _tag, cxx::min<unsigned long>(_l, Max_tag));
81           if (_l < Max_tag)
82             mycpy(&obuf, &rem, "             ", Max_tag-_l);
83
84           if (_in_line)
85             mycpy(&obuf, &rem, ": ", 2);
86           else
87             mycpy(&obuf, &rem, "| ", 2);
88         }
89
90       unsigned long i;
91       for (i = 0; i < len_msg; ++i)
92         if (msg[i] == '\n' || msg[i] == 0)
93           break;
94
95       mycpy(&obuf, &rem, msg, i);
96
97       if (i <len_msg && msg[i] == '\n')
98         {
99           if (color())
100             mycpy(&obuf, &rem, "\033[0m", 4);
101           mycpy(&obuf, &rem, "\n", 1);
102           _in_line = false;
103           last_log = 0;
104           ++i;
105         }
106       else
107         {
108           last_log = this;
109           _in_line = true;
110         }
111       my_outnstring(msgbuf, obuf-msgbuf);
112
113       msg += i;
114       len_msg -= i;
115     }
116
117   if (_in_line && color())
118     my_outnstring("\033[0m", 4);
119
120   // and finally done
121   return -L4_ENOREPLY;
122 }
123
124
125 int
126 Ldr::Log::color_value(cxx::String const &col)
127 {
128   int c = 0, bright = 0;
129
130   if (col.empty())
131     return 0;
132
133   switch(col[0])
134     {
135     case 'N': bright = 1; case 'n': c = 0; break;
136     case 'R': bright = 1; case 'r': c = 1; break;
137     case 'G': bright = 1; case 'g': c = 2; break;
138     case 'Y': bright = 1; case 'y': c = 3; break;
139     case 'B': bright = 1; case 'b': c = 4; break;
140     case 'M': bright = 1; case 'm': c = 5; break;
141     case 'C': bright = 1; case 'c': c = 6; break;
142     case 'W': bright = 1; case 'w': c = 7; break;
143     default: c = 0;
144     }
145
146   return (bright << 3) | c;
147 }
148