static const char *append_field(QString *outstr, const QError *qerror, const char *start) { QObject *obj; QDict *qdict; QString *key_qs; const char *end, *key; if (*start != '%') parse_error(qerror, '%'); start++; if (*start != '(') parse_error(qerror, '('); start++; end = strchr(start, ')'); if (!end) parse_error(qerror, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); qdict = qobject_to_qdict(qdict_get(qerror->error, "data")); obj = qdict_get(qdict, key); if (!obj) { qerror_abort(qerror, "key '%s' not found in QDict", key); } switch (qobject_type(obj)) { case QTYPE_QSTRING: qstring_append(outstr, qdict_get_str(qdict, key)); break; case QTYPE_QINT: qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: qerror_abort(qerror, "invalid type '%c'", qobject_type(obj)); } QDECREF(key_qs); return ++end; }
static void qerror_set_data(QError *qerr, const char *fmt, va_list *va) { QObject *obj; obj = qobject_from_jsonv(fmt, va); if (!obj) { qerror_abort(qerr, "invalid format '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "error format is not a QDict '%s'", fmt); } qerr->error = qobject_to_qdict(obj); obj = qdict_get(qerr->error, "class"); if (!obj) { qerror_abort(qerr, "missing 'class' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QSTRING) { qerror_abort(qerr, "'class' key value should be a QString"); } obj = qdict_get(qerr->error, "data"); if (!obj) { qerror_abort(qerr, "missing 'data' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "'data' key value should be a QDICT"); } }
static void qerror_set_desc(QError *qerr, const char *fmt) { int i; // FIXME: inefficient loop for (i = 0; qerror_table[i].error_fmt; i++) { if (strcmp(qerror_table[i].error_fmt, fmt) == 0) { qerr->entry = &qerror_table[i]; return; } } qerror_abort(qerr, "error format '%s' not found", fmt); }
/** * qerror_from_info(): Create a new QError from error information * * The information consists of: * * - file the file name of where the error occurred * - linenr the line number of where the error occurred * - func the function name of where the error occurred * - fmt JSON printf-like dictionary, there must exist keys 'class' and * 'data' * - va va_list of all arguments specified by fmt * * Return strong reference. */ QError *qerror_from_info(const char *file, int linenr, const char *func, const char *fmt, va_list *va) { QError *qerr; qerr = qerror_new(); qerr->linenr = linenr; qerr->file = file; qerr->func = func; if (!fmt) { qerror_abort(qerr, "QDict not specified"); } qerror_set_data(qerr, fmt, va); qerror_set_desc(qerr, fmt); return qerr; }
static void parse_error(const QError *qerror, int c) { qerror_abort(qerror, "expected '%c' in '%s'", c, qerror->entry->desc); }