/*
* fy-diag.h - diagnostics
*
* Copyright (c) 2019 Pantelis Antoniou <pantelis.antoniou@konsulko.com>
*
* SPDX-License-Identifier: MIT
*/
#ifndef FY_DIAG_H
#define FY_DIAG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <libfyaml.h>
#include "fy-list.h"
#include "fy-token.h"
#if !defined(NDEBUG) && defined(HAVE_DEVMODE) && HAVE_DEVMODE
#define FY_DEVMODE
#else
#undef FY_DEVMODE
#endif
/* error flags (above 0x100 is library specific) */
#define FYEF_SOURCE 0x0001
#define FYEF_POSITION 0x0002
#define FYEF_TYPE 0x0004
#define FYEF_USERSTART 0x0100
#define FYDF_LEVEL_SHIFT 0
#define FYDF_LEVEL_MASK (0x0f << FYDF_LEVEL_SHIFT)
#define FYDF_LEVEL(x) (((unsigned int)(x) << FYDF_LEVEL_SHIFT) & FYDF_LEVEL_MASK)
#define FYDF_DEBUG FYDF_LEVEL(FYET_DEBUG)
#define FYDF_INFO FYDF_LEVEL(FYET_INFO)
#define FYDF_NOTICE FYDF_LEVEL(FYET_NOTICE)
#define FYDF_WARNING FYDF_LEVEL(FYET_WARNING)
#define FYDF_ERROR FYDF_LEVEL(FYET_ERROR)
#define FYDF_MODULE_SHIFT 4
#define FYDF_MODULE_MASK (0x0f << FYDF_MODULE_SHIFT)
#define FYDF_MODULE(x) (((unsigned int)(x) << FYDF_MODULE_SHIFT) & FYDF_MODULE_MASK)
#define FYDF_ATOM FYDF_MODULE(FYEM_ATOM)
#define FYDF_SCANNER FYDF_MODULE(FYEM_SCANNER)
#define FYDF_PARSER FYDF_MODULE(FYEM_PARSER)
#define FYDF_TREE FYDF_MODULE(FYEM_TREE)
#define FYDF_BUILDER FYDF_MODULE(FYEM_BUILDER)
#define FYDF_INTERNAL FYDF_MODULE(FYEM_INTERNAL)
#define FYDF_SYSTEM FYDF_MODULE(FYEM_SYSTEM)
#define FYDF_MODULE_USER_MASK 7
#define FYDF_MODULE_USER(x) FYDF_MODULE(8 + ((x) & FYDF_MODULE_USER_MASK))
struct fy_diag_term_info {
int rows;
int columns;
};
struct fy_diag_report_ctx {
enum fy_error_type type;
enum fy_error_module module;
struct fy_token *fyt;
bool has_override;
const char *override_file;
int override_line;
int override_column;
};
FY_TYPE_FWD_DECL_LIST(diag_errorp);
struct fy_diag_errorp {
struct fy_list_head node;
char *space;
struct fy_diag_error e;
};
FY_TYPE_DECL_LIST(diag_errorp);
struct fy_diag {
struct fy_diag_cfg cfg;
int refs;
bool on_error : 1;
bool destroyed : 1;
bool collect_errors : 1;
bool terminal_probed : 1;
struct fy_diag_term_info term_info;
struct fy_diag_errorp_list errors;
};
void fy_diag_free(struct fy_diag *diag);
void fy_diag_vreport(struct fy_diag *diag,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_diag_report(struct fy_diag *diag,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define __FY_DEBUG_UNUSED__ /* nothing */
#else
#define __FY_DEBUG_UNUSED__ FY_ATTRIBUTE(__unused__)
#endif
/* parser diagnostics */
struct fy_parser;
void fy_diag_cfg_from_parser_flags(struct fy_diag_cfg *cfg, enum fy_parse_cfg_flags pflags);
int fy_parser_vdiag(struct fy_parser *fyp, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap);
int fy_parser_diag(struct fy_parser *fyp, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 6, 7));
void fy_diag_error_atom_display(struct fy_diag *diag, enum fy_error_type type,
struct fy_atom *atom);
void fy_diag_error_token_display(struct fy_diag *diag, enum fy_error_type type,
struct fy_token *fyt);
void fy_parser_diag_vreport(struct fy_parser *fyp,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_parser_diag_report(struct fy_parser *fyp,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define fyp_debug(_fyp, _module, _fmt, ...) \
fy_parser_diag((_fyp), FYET_DEBUG | FYDF_MODULE(_module), \
__FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#else
#define fyp_debug(_fyp, _module, _fmt, ...) \
do { } while(0)
#endif
#define fyp_info(_fyp, _fmt, ...) \
fy_parser_diag((_fyp), FYET_INFO, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyp_notice(_fyp, _fmt, ...) \
fy_parser_diag((_fyp), FYET_NOTICE, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyp_warning(_fyp, _fmt, ...) \
fy_parser_diag((_fyp), FYET_WARNING, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyp_error(_fyp, _fmt, ...) \
fy_parser_diag((_fyp), FYET_ERROR, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyp_scan_debug(_fyp, _fmt, ...) \
fyp_debug((_fyp), FYEM_SCAN, (_fmt) , ## __VA_ARGS__)
#define fyp_parse_debug(_fyp, _fmt, ...) \
fyp_debug((_fyp), FYEM_PARSE, (_fmt) , ## __VA_ARGS__)
#define fyp_doc_debug(_fyp, _fmt, ...) \
fyp_debug((_fyp), FYEM_DOC, (_fmt) , ## __VA_ARGS__)
#define fyp_error_check(_fyp, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
fyp_error((_fyp), _fmt, ## __VA_ARGS__); \
goto _label ; \
} \
} while(0)
#define _FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \
do { \
struct fy_diag_report_ctx _drc; \
memset(&_drc, 0, sizeof(_drc)); \
_drc.type = (_type); \
_drc.module = (_module); \
_drc.fyt = (_fyt); \
fy_parser_diag_report((_fyp), &_drc, (_fmt) , ## __VA_ARGS__); \
} while(0)
#define FYP_TOKEN_DIAG(_fyp, _fyt, _type, _module, _fmt, ...) \
_FYP_TOKEN_DIAG(_fyp, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
#define FYP_PARSE_DIAG(_fyp, _adv, _cnt, _type, _module, _fmt, ...) \
_FYP_TOKEN_DIAG(_fyp, \
fy_token_create(FYTT_INPUT_MARKER, \
fy_fill_atom_at((_fyp), (_adv), (_cnt), \
FY_ALLOCA(sizeof(struct fy_atom)))), \
_type, _module, _fmt, ## __VA_ARGS__)
#define FYP_MARK_DIAG(_fyp, _sm, _em, _type, _module, _fmt, ...) \
_FYP_TOKEN_DIAG(_fyp, \
fy_token_create(FYTT_INPUT_MARKER, \
fy_fill_atom_mark(((_fyp)), (_sm), (_em), \
FY_ALLOCA(sizeof(struct fy_atom)))), \
_type, _module, _fmt, ## __VA_ARGS__)
#define FYP_NODE_DIAG(_fyp, _fyn, _type, _module, _fmt, ...) \
_FYP_TOKEN_DIAG(_fyp, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
#define FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ...) \
FYP_TOKEN_DIAG(_fyp, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ...) \
FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ...) \
FYP_MARK_DIAG(_fyp, _sm, _em, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ...) \
FYP_NODE_DIAG(_fyp, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYP_TOKEN_ERROR_CHECK(_fyp, _fyt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYP_TOKEN_ERROR(_fyp, _fyt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYP_PARSE_ERROR_CHECK(_fyp, _adv, _cnt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYP_PARSE_ERROR(_fyp, _adv, _cnt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYP_MARK_ERROR_CHECK(_fyp, _sm, _em, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYP_MARK_ERROR(_fyp, _sm, _em, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYP_NODE_ERROR_CHECK(_fyp, _fyn, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYP_NODE_ERROR(_fyp, _fyn, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYP_TOKEN_WARNING(_fyp, _fyt, _module, _fmt, ...) \
FYP_TOKEN_DIAG(_fyp, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYP_PARSE_WARNING(_fyp, _adv, _cnt, _module, _fmt, ...) \
FYP_PARSE_DIAG(_fyp, _adv, _cnt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYP_MARK_WARNING(_fyp, _sm, _em, _module, _fmt, ...) \
FYP_MARK_DIAG(_fyp, _sm, _em, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYP_NODE_WARNING(_fyp, _fyn, _type, _module, _fmt, ...) \
FYP_NODE_DIAG(_fyp, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
/* reader diagnostics */
struct fy_reader;
int fy_reader_vdiag(struct fy_reader *fyr, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap);
int fy_reader_diag(struct fy_reader *fyr, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 6, 7));
void fy_reader_diag_vreport(struct fy_reader *fyr,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_reader_diag_report(struct fy_reader *fyr,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define fyr_debug(_fyr, _fmt, ...) \
fy_reader_diag((_fyr), FYET_DEBUG, \
__FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#else
#define fyr_debug(_fyr, _fmt, ...) \
do { } while(0)
#endif
#define fyr_info(_fyr, _fmt, ...) \
fy_reader_diag((_fyr), FYET_INFO, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyr_notice(_fyr, _fmt, ...) \
fy_reader_diag((_fyr), FYET_NOTICE, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyr_warning(_fyr, _fmt, ...) \
fy_reader_diag((_fyr), FYET_WARNING, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyr_error(_fyr, _fmt, ...) \
fy_reader_diag((_fyr), FYET_ERROR, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyr_error_check(_fyr, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
fyr_error((_fyr), _fmt, ## __VA_ARGS__); \
goto _label ; \
} \
} while(0)
#define _FYR_TOKEN_DIAG(_fyr, _fyt, _type, _module, _fmt, ...) \
do { \
struct fy_diag_report_ctx _drc; \
memset(&_drc, 0, sizeof(_drc)); \
_drc.type = (_type); \
_drc.module = (_module); \
_drc.fyt = (_fyt); \
fy_reader_diag_report((_fyr), &_drc, (_fmt) , ## __VA_ARGS__); \
} while(0)
#define FYR_TOKEN_DIAG(_fyr, _fyt, _type, _module, _fmt, ...) \
_FYR_TOKEN_DIAG(_fyr, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
#define FYR_PARSE_DIAG(_fyr, _adv, _cnt, _type, _module, _fmt, ...) \
_FYR_TOKEN_DIAG(_fyr, \
fy_token_create(FYTT_INPUT_MARKER, \
fy_reader_fill_atom_at((_fyr), (_adv), (_cnt), \
FY_ALLOCA(sizeof(struct fy_atom)))), \
_type, _module, _fmt, ## __VA_ARGS__)
#define FYR_MARK_DIAG(_fyr, _sm, _em, _type, _module, _fmt, ...) \
_FYR_TOKEN_DIAG(_fyr, \
fy_token_create(FYTT_INPUT_MARKER, \
fy_reader_fill_atom_mark(((_fyr)), (_sm), (_em), \
FY_ALLOCA(sizeof(struct fy_atom)))), \
_type, _module, _fmt, ## __VA_ARGS__)
#define FYR_NODE_DIAG(_fyr, _fyn, _type, _module, _fmt, ...) \
_FYR_TOKEN_DIAG(_fyr, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
#define FYR_TOKEN_ERROR(_fyr, _fyt, _module, _fmt, ...) \
FYR_TOKEN_DIAG(_fyr, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYR_PARSE_ERROR(_fyr, _adv, _cnt, _module, _fmt, ...) \
FYR_PARSE_DIAG(_fyr, _adv, _cnt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYR_MARK_ERROR(_fyr, _sm, _em, _module, _fmt, ...) \
FYR_MARK_DIAG(_fyr, _sm, _em, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYR_NODE_ERROR(_fyr, _fyn, _module, _fmt, ...) \
FYR_NODE_DIAG(_fyr, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYR_TOKEN_ERROR_CHECK(_fyr, _fyt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYR_TOKEN_ERROR(_fyr, _fyt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYR_PARSE_ERROR_CHECK(_fyr, _adv, _cnt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYR_PARSE_ERROR(_fyr, _adv, _cnt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYR_MARK_ERROR_CHECK(_fyr, _sm, _em, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYR_MARK_ERROR(_fyr, _sm, _em, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYR_NODE_ERROR_CHECK(_fyr, _fyn, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYR_NODE_ERROR(_fyr, _fyn, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYR_TOKEN_WARNING(_fyr, _fyt, _module, _fmt, ...) \
FYR_TOKEN_DIAG(_fyr, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYR_PARSE_WARNING(_fyr, _adv, _cnt, _module, _fmt, ...) \
FYR_PARSE_DIAG(_fyr, _adv, _cnt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYR_MARK_WARNING(_fyr, _sm, _em, _module, _fmt, ...) \
FYR_MARK_DIAG(_fyr, _sm, _em, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYR_NODE_WARNING(_fyr, _fyn, _type, _module, _fmt, ...) \
FYR_NODE_DIAG(_fyr, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
/* doc */
struct fy_document;
int fy_document_vdiag(struct fy_document *fyd, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap);
int fy_document_diag(struct fy_document *fyd, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 6, 7));
void fy_document_diag_vreport(struct fy_document *fyd,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_document_diag_report(struct fy_document *fyd,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define fyd_debug(_fyd, _module, _fmt, ...) \
fy_document_diag((_fyd), FYET_DEBUG | FYDF_MODULE(_module), \
__FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#else
#define fyd_debug(_fyd, _module, _fmt, ...) \
do { } while(0)
#endif
#define fyd_info(_fyd, _fmt, ...) \
fy_document_diag((_fyd), FYET_INFO, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyd_notice(_fyd, _fmt, ...) \
fy_document_diag((_fyd), FYET_NOTICE, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyd_warning(_fyd, _fmt, ...) \
fy_document_diag((_fyd), FYET_WARNING, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyd_error(_fyd, _fmt, ...) \
fy_document_diag((_fyd), FYET_ERROR, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyd_doc_debug(_fyd, _fmt, ...) \
fyd_debug((_fyd), FYEM_DOC, (_fmt) , ## __VA_ARGS__)
#define fyd_error_check(_fyd, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
fyd_error((_fyd), _fmt, ## __VA_ARGS__); \
goto _label ; \
} \
} while(0)
#define _FYD_TOKEN_DIAG(_fyd, _fyt, _type, _module, _fmt, ...) \
do { \
struct fy_diag_report_ctx _drc; \
memset(&_drc, 0, sizeof(_drc)); \
_drc.type = (_type); \
_drc.module = (_module); \
_drc.fyt = (_fyt); \
fy_document_diag_report((_fyd), &_drc, (_fmt) , ## __VA_ARGS__); \
} while(0)
#define FYD_TOKEN_DIAG(_fyd, _fyt, _type, _module, _fmt, ...) \
_FYD_TOKEN_DIAG(_fyd, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
#define FYD_NODE_DIAG(_fyd, _fyn, _type, _module, _fmt, ...) \
_FYD_TOKEN_DIAG(_fyd, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
#define FYD_TOKEN_ERROR(_fyd, _fyt, _module, _fmt, ...) \
FYD_TOKEN_DIAG(_fyd, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYD_NODE_ERROR(_fyd, _fyn, _module, _fmt, ...) \
FYD_NODE_DIAG(_fyd, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYD_TOKEN_ERROR_CHECK(_fyd, _fyt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYD_TOKEN_ERROR(_fyd, _fyt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYD_NODE_ERROR_CHECK(_fyd, _fyn, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYD_NODE_ERROR(_fyd, _fyn, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYD_TOKEN_WARNING(_fyd, _fyt, _module, _fmt, ...) \
FYD_TOKEN_DIAG(_fyd, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
#define FYD_NODE_WARNING(_fyd, _fyn, _type, _module, _fmt, ...) \
FYD_NODE_DIAG(_fyd, _fyn, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
/* composer */
struct fy_composer;
int fy_composer_vdiag(struct fy_composer *fyc, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap);
int fy_composer_diag(struct fy_composer *fyc, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 6, 7));
void fy_composer_diag_vreport(struct fy_composer *fyc,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_composer_diag_report(struct fy_composer *fyc,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define fyc_debug(_fyc, _module, _fmt, ...) \
fy_composer_diag((_fyc), FYET_DEBUG | FYDF_MODULE(_module), \
__FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#else
#define fyc_debug(_fyc, _module, _fmt, ...) \
do { } while(0)
#endif
#define fyc_info(_fyc, _fmt, ...) \
fy_composer_diag((_fyc), FYET_INFO, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyc_notice(_fyc, _fmt, ...) \
fy_composer_diag((_fyc), FYET_NOTICE, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyc_warning(_fyc, _fmt, ...) \
fy_composer_diag((_fyc), FYET_WARNING, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyc_error(_fyc, _fmt, ...) \
fy_composer_diag((_fyc), FYET_ERROR, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fyc_error_check(_fyc, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
fyc_error((_fyc), _fmt, ## __VA_ARGS__); \
goto _label ; \
} \
} while(0)
#define _FYC_TOKEN_DIAG(_fyc, _fyt, _type, _module, _fmt, ...) \
do { \
struct fy_diag_report_ctx _drc; \
memset(&_drc, 0, sizeof(_drc)); \
_drc.type = (_type); \
_drc.module = (_module); \
_drc.fyt = (_fyt); \
fy_composer_diag_report((_fyc), &_drc, (_fmt) , ## __VA_ARGS__); \
} while(0)
#define FYC_TOKEN_DIAG(_fyc, _fyt, _type, _module, _fmt, ...) \
_FYC_TOKEN_DIAG(_fyc, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
#define FYC_NODE_DIAG(_fyc, _fyn, _type, _module, _fmt, ...) \
_FYC_TOKEN_DIAG(_fyc, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
#define FYC_TOKEN_ERROR(_fyc, _fyt, _module, _fmt, ...) \
FYC_TOKEN_DIAG(_fyc, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYC_TOKEN_ERROR_CHECK(_fyc, _fyt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYC_TOKEN_ERROR(_fyc, _fyt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYC_TOKEN_WARNING(_fyc, _fyt, _module, _fmt, ...) \
FYC_TOKEN_DIAG(_fyc, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
/* document builder */
struct fy_document_builder;
int fy_document_builder_vdiag(struct fy_document_builder *fydb, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, va_list ap);
int fy_document_builder_diag(struct fy_document_builder *fydb, unsigned int flags,
const char *file, int line, const char *func,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 6, 7));
void fy_document_builder_diag_vreport(struct fy_document_builder *fydb,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, va_list ap);
void fy_document_builder_diag_report(struct fy_document_builder *fydb,
const struct fy_diag_report_ctx *fydrc,
const char *fmt, ...)
FY_ATTRIBUTE(format(printf, 3, 4));
#ifdef FY_DEVMODE
#define fydb_debug(_fydb, _module, _fmt, ...) \
fy_document_builder_diag((_fydb), FYET_DEBUG | FYDF_MODULE(_module), \
__FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#else
#define fydb_debug(_fydb, _module, _fmt, ...) \
do { } while(0)
#endif
#define fydb_info(_fydb, _fmt, ...) \
fy_document_builder_diag((_fydb), FYET_INFO, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fydb_notice(_fydb, _fmt, ...) \
fy_document_builder_diag((_fydb), FYET_NOTICE, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fydb_warning(_fydb, _fmt, ...) \
fy_document_builder_diag((_fydb), FYET_WARNING, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fydb_error(_fydb, _fmt, ...) \
fy_document_builder_diag((_fydb), FYET_ERROR, __FILE__, __LINE__, __func__, \
(_fmt) , ## __VA_ARGS__)
#define fydb_error_check(_fydb, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
fydb_error((_fydb), _fmt, ## __VA_ARGS__); \
goto _label ; \
} \
} while(0)
#define _FYDB_TOKEN_DIAG(_fydb, _fyt, _type, _module, _fmt, ...) \
do { \
struct fy_diag_report_ctx _drc; \
memset(&_drc, 0, sizeof(_drc)); \
_drc.type = (_type); \
_drc.module = (_module); \
_drc.fyt = (_fyt); \
fy_document_builder_diag_report((_fydb), &_drc, (_fmt) , ## __VA_ARGS__); \
} while(0)
#define FYDB_TOKEN_DIAG(_fydb, _fyt, _type, _module, _fmt, ...) \
_FYDB_TOKEN_DIAG(_fydb, fy_token_ref(_fyt), _type, _module, _fmt, ## __VA_ARGS__)
#define FYDB_NODE_DIAG(_fydb, _fyn, _type, _module, _fmt, ...) \
_FYDB_TOKEN_DIAG(_fydb, fy_node_token(_fyn), _type, _module, _fmt, ## __VA_ARGS__)
#define FYDB_TOKEN_ERROR(_fydb, _fyt, _module, _fmt, ...) \
FYDB_TOKEN_DIAG(_fydb, _fyt, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYDB_NODE_ERROR(_fydb, _fyn, _module, _fmt, ...) \
FYDB_NODE_DIAG(_fydb, _fyn, FYET_ERROR, _module, _fmt, ## __VA_ARGS__)
#define FYDB_TOKEN_ERROR_CHECK(_fydb, _fyt, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYDB_TOKEN_ERROR(_fydb, _fyt, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYDB_NODE_ERROR_CHECK(_fydb, _fyn, _module, _cond, _label, _fmt, ...) \
do { \
if (!(_cond)) { \
FYDB_NODE_ERROR(_fydb, _fyn, _module, _fmt, ## __VA_ARGS__); \
goto _label; \
} \
} while(0)
#define FYDB_TOKEN_WARNING(_fydb, _fyt, _module, _fmt, ...) \
FYDB_TOKEN_DIAG(_fydb, _fyt, FYET_WARNING, _module, _fmt, ## __VA_ARGS__)
/* alloca formatted print methods */
#define alloca_vsprintf(_res, _fmt, _ap) \
do { \
const char *__fmt = (_fmt); \
va_list _ap_orig; \
int _size; \
int _sizew __FY_DEBUG_UNUSED__; \
char *_buf = NULL, *_s; \
\
va_copy(_ap_orig, (_ap)); \
_size = vsnprintf(NULL, 0, __fmt, _ap_orig); \
va_end(_ap_orig); \
if (_size != -1) { \
_buf = FY_ALLOCA(_size + 1); \
_sizew = vsnprintf(_buf, _size + 1, __fmt, _ap); \
assert(_size == _sizew); \
_s = _buf + strlen(_buf); \
while (_s > _buf && _s[-1] == '\n') \
*--_s = '\0'; \
} \
*(_res) = _buf; \
} while(false)
#define alloca_sprintf(_res, _fmt, ...) \
do { \
const char *__fmt = (_fmt); \
int _size; \
int _sizew __FY_DEBUG_UNUSED__; \
char *_buf = NULL, *_s; \
\
_size = snprintf(NULL, 0, __fmt, ## __VA_ARGS__); \
if (_size != -1) { \
_buf = FY_ALLOCA(_size + 1); \
_sizew = snprintf(_buf, _size + 1, __fmt, __VA_ARGS__); \
assert(_size == _sizew); \
_s = _buf + strlen(_buf); \
while (_s > _buf && _s[-1] == '\n') \
*--_s = '\0'; \
} \
*(_res) = _buf; \
} while(false)
#endif