File:  [Qemu by Fabrice Bellard] / qemu / qemu-error.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:55:29 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, qemu1000, qemu0151, HEAD
qemu 0.15.1

    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.
  196:  * Format arguments like sprintf().  The result should not contain
  197:  * newlines.
  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