File:  [Qemu by Fabrice Bellard] / qemu / qemu-error.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:23:00 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, qemu0130, HEAD
qemu 0.13.0

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

unix.superglobalmegacorp.com