Annotation of qemu/qemu-error.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com