Statistics
| Branch: | Revision:

root / qemu-error.c @ a0a3167a

History | View | Annotate | Download (4.3 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 827b0813 Markus Armbruster
/*
161 827b0813 Markus Armbruster
 * Print current location to current monitor if we have one, else to stderr.
162 827b0813 Markus Armbruster
 */
163 827b0813 Markus Armbruster
void error_print_loc(void)
164 827b0813 Markus Armbruster
{
165 65abca0a Markus Armbruster
    const char *sep = "";
166 0f0bc3f1 Markus Armbruster
    int i;
167 0f0bc3f1 Markus Armbruster
    const char *const *argp;
168 65abca0a Markus Armbruster
169 6627f645 Markus Armbruster
    if (!cur_mon && progname) {
170 65abca0a Markus Armbruster
        fprintf(stderr, "%s:", progname);
171 65abca0a Markus Armbruster
        sep = " ";
172 65abca0a Markus Armbruster
    }
173 827b0813 Markus Armbruster
    switch (cur_loc->kind) {
174 0f0bc3f1 Markus Armbruster
    case LOC_CMDLINE:
175 0f0bc3f1 Markus Armbruster
        argp = cur_loc->ptr;
176 0f0bc3f1 Markus Armbruster
        for (i = 0; i < cur_loc->num; i++) {
177 0f0bc3f1 Markus Armbruster
            error_printf("%s%s", sep, argp[i]);
178 0f0bc3f1 Markus Armbruster
            sep = " ";
179 0f0bc3f1 Markus Armbruster
        }
180 0f0bc3f1 Markus Armbruster
        error_printf(": ");
181 0f0bc3f1 Markus Armbruster
        break;
182 cf5a65aa Markus Armbruster
    case LOC_FILE:
183 cf5a65aa Markus Armbruster
        error_printf("%s:", (const char *)cur_loc->ptr);
184 cf5a65aa Markus Armbruster
        if (cur_loc->num) {
185 cf5a65aa Markus Armbruster
            error_printf("%d:", cur_loc->num);
186 cf5a65aa Markus Armbruster
        }
187 cf5a65aa Markus Armbruster
        error_printf(" ");
188 cf5a65aa Markus Armbruster
        break;
189 65abca0a Markus Armbruster
    default:
190 bb334b12 Edgar E. Iglesias
        error_printf("%s", sep);
191 827b0813 Markus Armbruster
    }
192 827b0813 Markus Armbruster
}
193 827b0813 Markus Armbruster
194 1ecda02b Markus Armbruster
/*
195 1ecda02b Markus Armbruster
 * Print an error message to current monitor if we have one, else to stderr.
196 6daf194d Markus Armbruster
 * Format arguments like sprintf().  The result should not contain
197 6daf194d Markus Armbruster
 * newlines.
198 827b0813 Markus Armbruster
 * Prepend the current location and append a newline.
199 ab5b027e Markus Armbruster
 * It's wrong to call this in a QMP monitor.  Use qerror_report() there.
200 1ecda02b Markus Armbruster
 */
201 1ecda02b Markus Armbruster
void error_report(const char *fmt, ...)
202 ba0fe87a Markus Armbruster
{
203 ba0fe87a Markus Armbruster
    va_list ap;
204 ba0fe87a Markus Armbruster
205 827b0813 Markus Armbruster
    error_print_loc();
206 ba0fe87a Markus Armbruster
    va_start(ap, fmt);
207 ba0fe87a Markus Armbruster
    error_vprintf(fmt, ap);
208 ba0fe87a Markus Armbruster
    va_end(ap);
209 1ecda02b Markus Armbruster
    error_printf("\n");
210 b4a51f7f Markus Armbruster
}