root / qemu-error.c @ 09f1bbcd
History | View | Annotate | Download (4.4 kB)
1 | ba0fe87a | Markus Armbruster | /*
|
---|---|---|---|
2 | ba0fe87a | Markus Armbruster | * Error reporting
|
3 | ba0fe87a | Markus Armbruster | *
|
4 | ba0fe87a | Markus Armbruster | * Copyright (C) 2010 Red Hat Inc.
|
5 | ba0fe87a | Markus Armbruster | *
|
6 | ba0fe87a | Markus Armbruster | * Authors:
|
7 | ba0fe87a | Markus Armbruster | * Markus Armbruster <armbru@redhat.com>,
|
8 | ba0fe87a | Markus Armbruster | *
|
9 | ba0fe87a | Markus Armbruster | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | ba0fe87a | Markus Armbruster | * See the COPYING file in the top-level directory.
|
11 | ba0fe87a | Markus Armbruster | */
|
12 | ba0fe87a | Markus Armbruster | |
13 | b4a51f7f | Markus Armbruster | #include <stdio.h> |
14 | b4a51f7f | Markus Armbruster | #include "monitor.h" |
15 | b4a51f7f | Markus Armbruster | |
16 | ba0fe87a | Markus Armbruster | /*
|
17 | ba0fe87a | Markus Armbruster | * Print to current monitor if we have one, else to stderr.
|
18 | ba0fe87a | Markus Armbruster | * TODO should return int, so callers can calculate width, but that
|
19 | ba0fe87a | Markus Armbruster | * requires surgery to monitor_vprintf(). Left for another day.
|
20 | ba0fe87a | Markus Armbruster | */
|
21 | ba0fe87a | Markus Armbruster | void error_vprintf(const char *fmt, va_list ap) |
22 | b4a51f7f | Markus Armbruster | { |
23 | 6e4f984c | Markus Armbruster | if (cur_mon) {
|
24 | ba0fe87a | Markus Armbruster | monitor_vprintf(cur_mon, fmt, ap); |
25 | 6e4f984c | Markus Armbruster | } else {
|
26 | ba0fe87a | Markus Armbruster | vfprintf(stderr, fmt, ap); |
27 | b4a51f7f | Markus Armbruster | } |
28 | ba0fe87a | Markus Armbruster | } |
29 | ba0fe87a | Markus Armbruster | |
30 | ba0fe87a | Markus Armbruster | /*
|
31 | ba0fe87a | Markus Armbruster | * Print to current monitor if we have one, else to stderr.
|
32 | ba0fe87a | Markus Armbruster | * TODO just like error_vprintf()
|
33 | ba0fe87a | Markus Armbruster | */
|
34 | ba0fe87a | Markus Armbruster | void error_printf(const char *fmt, ...) |
35 | ba0fe87a | Markus Armbruster | { |
36 | ba0fe87a | Markus Armbruster | va_list ap; |
37 | ba0fe87a | Markus Armbruster | |
38 | ba0fe87a | Markus Armbruster | va_start(ap, fmt); |
39 | ba0fe87a | Markus Armbruster | error_vprintf(fmt, ap); |
40 | ba0fe87a | Markus Armbruster | va_end(ap); |
41 | ba0fe87a | Markus Armbruster | } |
42 | ba0fe87a | Markus Armbruster | |
43 | aa924ae7 | Markus Armbruster | void error_printf_unless_qmp(const char *fmt, ...) |
44 | aa924ae7 | Markus Armbruster | { |
45 | aa924ae7 | Markus Armbruster | va_list ap; |
46 | aa924ae7 | Markus Armbruster | |
47 | aa924ae7 | Markus Armbruster | if (!monitor_cur_is_qmp()) {
|
48 | aa924ae7 | Markus Armbruster | va_start(ap, fmt); |
49 | aa924ae7 | Markus Armbruster | error_vprintf(fmt, ap); |
50 | aa924ae7 | Markus Armbruster | va_end(ap); |
51 | aa924ae7 | Markus Armbruster | } |
52 | aa924ae7 | Markus Armbruster | } |
53 | aa924ae7 | Markus Armbruster | |
54 | 827b0813 | Markus Armbruster | static Location std_loc = {
|
55 | 827b0813 | Markus Armbruster | .kind = LOC_NONE |
56 | 827b0813 | Markus Armbruster | }; |
57 | 827b0813 | Markus Armbruster | static Location *cur_loc = &std_loc;
|
58 | 827b0813 | Markus Armbruster | |
59 | 827b0813 | Markus Armbruster | /*
|
60 | 827b0813 | Markus Armbruster | * Push location saved in LOC onto the location stack, return it.
|
61 | 827b0813 | Markus Armbruster | * The top of that stack is the current location.
|
62 | 827b0813 | Markus Armbruster | * Needs a matching loc_pop().
|
63 | 827b0813 | Markus Armbruster | */
|
64 | 827b0813 | Markus Armbruster | Location *loc_push_restore(Location *loc) |
65 | 827b0813 | Markus Armbruster | { |
66 | 827b0813 | Markus Armbruster | assert(!loc->prev); |
67 | 827b0813 | Markus Armbruster | loc->prev = cur_loc; |
68 | 827b0813 | Markus Armbruster | cur_loc = loc; |
69 | 827b0813 | Markus Armbruster | return loc;
|
70 | 827b0813 | Markus Armbruster | } |
71 | 827b0813 | Markus Armbruster | |
72 | 827b0813 | Markus Armbruster | /*
|
73 | 827b0813 | Markus Armbruster | * Initialize *LOC to "nowhere", push it onto the location stack.
|
74 | 827b0813 | Markus Armbruster | * The top of that stack is the current location.
|
75 | 827b0813 | Markus Armbruster | * Needs a matching loc_pop().
|
76 | 827b0813 | Markus Armbruster | * Return LOC.
|
77 | 827b0813 | Markus Armbruster | */
|
78 | 827b0813 | Markus Armbruster | Location *loc_push_none(Location *loc) |
79 | 827b0813 | Markus Armbruster | { |
80 | 827b0813 | Markus Armbruster | loc->kind = LOC_NONE; |
81 | 827b0813 | Markus Armbruster | loc->prev = NULL;
|
82 | 827b0813 | Markus Armbruster | return loc_push_restore(loc);
|
83 | 827b0813 | Markus Armbruster | } |
84 | 827b0813 | Markus Armbruster | |
85 | 827b0813 | Markus Armbruster | /*
|
86 | 827b0813 | Markus Armbruster | * Pop the location stack.
|
87 | 827b0813 | Markus Armbruster | * LOC must be the current location, i.e. the top of the stack.
|
88 | 827b0813 | Markus Armbruster | */
|
89 | 827b0813 | Markus Armbruster | Location *loc_pop(Location *loc) |
90 | 827b0813 | Markus Armbruster | { |
91 | 827b0813 | Markus Armbruster | assert(cur_loc == loc && loc->prev); |
92 | 827b0813 | Markus Armbruster | cur_loc = loc->prev; |
93 | 827b0813 | Markus Armbruster | loc->prev = NULL;
|
94 | 827b0813 | Markus Armbruster | return loc;
|
95 | 827b0813 | Markus Armbruster | } |
96 | 827b0813 | Markus Armbruster | |
97 | 827b0813 | Markus Armbruster | /*
|
98 | 827b0813 | Markus Armbruster | * Save the current location in LOC, return LOC.
|
99 | 827b0813 | Markus Armbruster | */
|
100 | 827b0813 | Markus Armbruster | Location *loc_save(Location *loc) |
101 | 827b0813 | Markus Armbruster | { |
102 | 827b0813 | Markus Armbruster | *loc = *cur_loc; |
103 | 827b0813 | Markus Armbruster | loc->prev = NULL;
|
104 | 827b0813 | Markus Armbruster | return loc;
|
105 | 827b0813 | Markus Armbruster | } |
106 | 827b0813 | Markus Armbruster | |
107 | 827b0813 | Markus Armbruster | /*
|
108 | 827b0813 | Markus Armbruster | * Change the current location to the one saved in LOC.
|
109 | 827b0813 | Markus Armbruster | */
|
110 | 827b0813 | Markus Armbruster | void loc_restore(Location *loc)
|
111 | 827b0813 | Markus Armbruster | { |
112 | 827b0813 | Markus Armbruster | Location *prev = cur_loc->prev; |
113 | 827b0813 | Markus Armbruster | assert(!loc->prev); |
114 | 827b0813 | Markus Armbruster | *cur_loc = *loc; |
115 | 827b0813 | Markus Armbruster | cur_loc->prev = prev; |
116 | 827b0813 | Markus Armbruster | } |
117 | 827b0813 | Markus Armbruster | |
118 | 827b0813 | Markus Armbruster | /*
|
119 | 827b0813 | Markus Armbruster | * Change the current location to "nowhere in particular".
|
120 | 827b0813 | Markus Armbruster | */
|
121 | 827b0813 | Markus Armbruster | void loc_set_none(void) |
122 | 827b0813 | Markus Armbruster | { |
123 | 827b0813 | Markus Armbruster | cur_loc->kind = LOC_NONE; |
124 | 827b0813 | Markus Armbruster | } |
125 | 827b0813 | Markus Armbruster | |
126 | cf5a65aa | Markus Armbruster | /*
|
127 | 0f0bc3f1 | Markus Armbruster | * Change the current location to argument ARGV[IDX..IDX+CNT-1].
|
128 | 0f0bc3f1 | Markus Armbruster | */
|
129 | 0f0bc3f1 | Markus Armbruster | void loc_set_cmdline(char **argv, int idx, int cnt) |
130 | 0f0bc3f1 | Markus Armbruster | { |
131 | 0f0bc3f1 | Markus Armbruster | cur_loc->kind = LOC_CMDLINE; |
132 | 0f0bc3f1 | Markus Armbruster | cur_loc->num = cnt; |
133 | 0f0bc3f1 | Markus Armbruster | cur_loc->ptr = argv + idx; |
134 | 0f0bc3f1 | Markus Armbruster | } |
135 | 0f0bc3f1 | Markus Armbruster | |
136 | 0f0bc3f1 | Markus Armbruster | /*
|
137 | cf5a65aa | Markus Armbruster | * Change the current location to file FNAME, line LNO.
|
138 | cf5a65aa | Markus Armbruster | */
|
139 | cf5a65aa | Markus Armbruster | void loc_set_file(const char *fname, int lno) |
140 | cf5a65aa | Markus Armbruster | { |
141 | cf5a65aa | Markus Armbruster | assert (fname || cur_loc->kind == LOC_FILE); |
142 | cf5a65aa | Markus Armbruster | cur_loc->kind = LOC_FILE; |
143 | cf5a65aa | Markus Armbruster | cur_loc->num = lno; |
144 | cf5a65aa | Markus Armbruster | if (fname) {
|
145 | cf5a65aa | Markus Armbruster | cur_loc->ptr = fname; |
146 | cf5a65aa | Markus Armbruster | } |
147 | cf5a65aa | Markus Armbruster | } |
148 | cf5a65aa | Markus Armbruster | |
149 | 65abca0a | Markus Armbruster | static const char *progname; |
150 | 65abca0a | Markus Armbruster | |
151 | 65abca0a | Markus Armbruster | /*
|
152 | 65abca0a | Markus Armbruster | * Set the program name for error_print_loc().
|
153 | 65abca0a | Markus Armbruster | */
|
154 | 65abca0a | Markus Armbruster | void error_set_progname(const char *argv0) |
155 | 65abca0a | Markus Armbruster | { |
156 | 65abca0a | Markus Armbruster | const char *p = strrchr(argv0, '/'); |
157 | 65abca0a | Markus Armbruster | progname = p ? p + 1 : argv0;
|
158 | 65abca0a | Markus Armbruster | } |
159 | 65abca0a | Markus Armbruster | |
160 | 7636a470 | michael@ozlabs.org | const char *error_get_progname(void) |
161 | 7636a470 | michael@ozlabs.org | { |
162 | 7636a470 | michael@ozlabs.org | return progname;
|
163 | 7636a470 | michael@ozlabs.org | } |
164 | 7636a470 | michael@ozlabs.org | |
165 | 827b0813 | Markus Armbruster | /*
|
166 | 827b0813 | Markus Armbruster | * Print current location to current monitor if we have one, else to stderr.
|
167 | 827b0813 | Markus Armbruster | */
|
168 | 827b0813 | Markus Armbruster | void error_print_loc(void) |
169 | 827b0813 | Markus Armbruster | { |
170 | 65abca0a | Markus Armbruster | const char *sep = ""; |
171 | 0f0bc3f1 | Markus Armbruster | int i;
|
172 | 0f0bc3f1 | Markus Armbruster | const char *const *argp; |
173 | 65abca0a | Markus Armbruster | |
174 | 6627f645 | Markus Armbruster | if (!cur_mon && progname) {
|
175 | 65abca0a | Markus Armbruster | fprintf(stderr, "%s:", progname);
|
176 | 65abca0a | Markus Armbruster | sep = " ";
|
177 | 65abca0a | Markus Armbruster | } |
178 | 827b0813 | Markus Armbruster | switch (cur_loc->kind) {
|
179 | 0f0bc3f1 | Markus Armbruster | case LOC_CMDLINE:
|
180 | 0f0bc3f1 | Markus Armbruster | argp = cur_loc->ptr; |
181 | 0f0bc3f1 | Markus Armbruster | for (i = 0; i < cur_loc->num; i++) { |
182 | 0f0bc3f1 | Markus Armbruster | error_printf("%s%s", sep, argp[i]);
|
183 | 0f0bc3f1 | Markus Armbruster | sep = " ";
|
184 | 0f0bc3f1 | Markus Armbruster | } |
185 | 0f0bc3f1 | Markus Armbruster | error_printf(": ");
|
186 | 0f0bc3f1 | Markus Armbruster | break;
|
187 | cf5a65aa | Markus Armbruster | case LOC_FILE:
|
188 | cf5a65aa | Markus Armbruster | error_printf("%s:", (const char *)cur_loc->ptr); |
189 | cf5a65aa | Markus Armbruster | if (cur_loc->num) {
|
190 | cf5a65aa | Markus Armbruster | error_printf("%d:", cur_loc->num);
|
191 | cf5a65aa | Markus Armbruster | } |
192 | cf5a65aa | Markus Armbruster | error_printf(" ");
|
193 | cf5a65aa | Markus Armbruster | break;
|
194 | 65abca0a | Markus Armbruster | default:
|
195 | bb334b12 | Edgar E. Iglesias | error_printf("%s", sep);
|
196 | 827b0813 | Markus Armbruster | } |
197 | 827b0813 | Markus Armbruster | } |
198 | 827b0813 | Markus Armbruster | |
199 | 1ecda02b | Markus Armbruster | /*
|
200 | 1ecda02b | Markus Armbruster | * Print an error message to current monitor if we have one, else to stderr.
|
201 | 6daf194d | Markus Armbruster | * Format arguments like sprintf(). The result should not contain
|
202 | 6daf194d | Markus Armbruster | * newlines.
|
203 | 827b0813 | Markus Armbruster | * Prepend the current location and append a newline.
|
204 | ab5b027e | Markus Armbruster | * It's wrong to call this in a QMP monitor. Use qerror_report() there.
|
205 | 1ecda02b | Markus Armbruster | */
|
206 | 1ecda02b | Markus Armbruster | void error_report(const char *fmt, ...) |
207 | ba0fe87a | Markus Armbruster | { |
208 | ba0fe87a | Markus Armbruster | va_list ap; |
209 | ba0fe87a | Markus Armbruster | |
210 | 827b0813 | Markus Armbruster | error_print_loc(); |
211 | ba0fe87a | Markus Armbruster | va_start(ap, fmt); |
212 | ba0fe87a | Markus Armbruster | error_vprintf(fmt, ap); |
213 | ba0fe87a | Markus Armbruster | va_end(ap); |
214 | 1ecda02b | Markus Armbruster | error_printf("\n");
|
215 | b4a51f7f | Markus Armbruster | } |