tmus

TUI Music Player
git clone https://git.sinitax.com/sinitax/tmus
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit 099002715d30af646d4582ac2b14322dae3f04d9
parent 44070fb5518e2b54748d58da5a5c61f476ef8700
Author: Louis Burda <quent.burda@gmail.com>
Date:   Thu, 12 Jan 2023 15:50:56 +0100

Refactor error handling

Diffstat:
Msrc/cmd.c | 101++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/data.c | 33++++++++++-----------------------
Msrc/history.c | 5++---
Msrc/log.c | 13+++++++++++--
Msrc/log.h | 1+
Msrc/mpris.c | 3+--
Msrc/player.c | 2+-
Msrc/player.h | 8+++++++-
Msrc/player_mpd.c | 18+++++++++---------
Msrc/player_mplay.c | 23+++++++++++------------
Msrc/ref.c | 4+---
Msrc/strbuf.c | 5++---
Msrc/tui.c | 9+--------
Msrc/tui.h | 14++++++++++++--
Msrc/util.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/util.h | 15+++++++++++++--
16 files changed, 203 insertions(+), 121 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c @@ -10,11 +10,6 @@ #include <stdbool.h> #include <string.h> -#define CMD_ERROR(...) do { \ - CMD_SET_STATUS(__VA_ARGS__); \ - return false; \ - } while (0) - static const struct cmd *last_cmd; static char *last_args; @@ -54,39 +49,52 @@ cmd_move(const char *name) char *newpath; tag = tag_find(name); - if (!tag) CMD_ERROR("Tag not found"); + if (!tag) { + CMD_SET_STATUS("Tag not found"); + return false; + } link = list_at(tracks_vis, track_nav.sel); - if (!link) CMD_ERROR("No track selected"); + if (!link) { + CMD_SET_STATUS("No track selected"); + return false; + } track = tracks_vis_track(link); - if (track->tag == tag) - CMD_ERROR("Same tag"); + if (track->tag == tag) { + CMD_SET_STATUS("Same tag"); + return false; + } newpath = aprintf("%s/%s", tag->fpath, track->name); if (path_exists(newpath)) { free(newpath); - CMD_ERROR("File already exists"); + CMD_SET_STATUS("File already exists"); + return false; } if (!dup_file(track->fpath, newpath)) { free(newpath); - CMD_ERROR("Failed to move track"); + CMD_SET_STATUS("Failed to move track"); + return false; } free(newpath); new = track_add(tag, track->name); if (!new) { - rm_file(track->fpath); - ERROR("Failed to move track"); + track_rm(new, true); + CMD_SET_STATUS("Failed to move track"); + return false; } if (player.track == track) player.track = new; - if (!track_rm(track, true)) - ERROR("Failed to move track"); + if (!track_rm(track, true)) { + CMD_SET_STATUS("Failed to move track"); + return false; + } return true; } @@ -100,31 +108,42 @@ cmd_copy(const char *name) char *newpath; tag = tag_find(name); - if (!tag) CMD_ERROR("Tag not found"); + if (!tag) { + CMD_SET_STATUS("Tag not found"); + return false; + } link = list_at(tracks_vis, track_nav.sel); - if (!link) CMD_ERROR("No track selected"); + if (!link) { + CMD_SET_STATUS("No track selected"); + return false; + } track = tracks_vis_track(link); - if (track->tag == tag) - CMD_ERROR("Same tag"); + if (track->tag == tag) { + CMD_SET_STATUS("Same tag"); + return false; + } newpath = aprintf("%s/%s", tag->fpath, track->name); if (path_exists(newpath)) { free(newpath); - CMD_ERROR("File already exists"); + CMD_SET_STATUS("File already exists"); + return false; } if (!dup_file(track->fpath, newpath)) { free(newpath); - CMD_ERROR("Failed to copy track"); + CMD_SET_STATUS("Failed to copy track"); + return false; } free(newpath); new = track_add(tag, track->name); if (!new) { rm_file(track->fpath); - CMD_ERROR("Failed to copy track"); + CMD_SET_STATUS("Failed to copy track"); + return false; } return true; @@ -215,21 +234,27 @@ cmd_add_tag(const char *name) for (LIST_ITER(&tags, link)) { tag = UPCAST(link, struct tag, link); - if (!strcmp(tag->name, name)) - CMD_ERROR("Tag already exists"); + if (!strcmp(tag->name, name)) { + CMD_SET_STATUS("Tag already exists"); + return false; + } } fpath = aprintf("%s/%s", datadir, name); if (!make_dir(fpath)) { free(fpath); - CMD_ERROR("Failed to create dir"); + CMD_SET_STATUS("Failed to create dir"); + return false; } free(fpath); tag = tag_add(name); - if (!tag) CMD_ERROR("Failed to add tag"); + if (!tag) { + CMD_SET_STATUS("Failed to add tag"); + return false; + } return true; } @@ -251,12 +276,16 @@ cmd_rm_tag(const char *name) break; } - if (!LIST_INNER(link)) - CMD_ERROR("No such tag"); + if (!LIST_INNER(link)) { + CMD_SET_STATUS("No such tag"); + return false; + } } - if (!tag_rm(tag, true)) - CMD_ERROR("Failed to remove tag"); + if (!tag_rm(tag, true)) { + CMD_SET_STATUS("Failed to remove tag"); + return false; + } return true; } @@ -268,8 +297,10 @@ cmd_rename(const char *name) struct track *track; struct tag *tag; - if (!*name) - CMD_ERROR("Supply a name"); + if (!*name) { + CMD_SET_STATUS("Supply a name"); + return false; + } ASSERT(pane_sel == cmd_pane); @@ -331,8 +362,10 @@ cmd_run(const char *query, bool *found) bool cmd_rerun(void) { - if (!last_cmd || !last_args) - CMD_ERROR("No command to repeat"); + if (!last_cmd || !last_args) { + CMD_SET_STATUS("No command to repeat"); + return false; + } return last_cmd->func(last_args); } diff --git a/src/data.c b/src/data.c @@ -1,15 +1,14 @@ #include "data.h" +#include "tui.h" #include "player.h" #include "list.h" #include "log.h" -#include "tui.h" #include <fts.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> -#include <err.h> #include <stdbool.h> #include <string.h> @@ -21,8 +20,6 @@ struct list tags_sel; /* struct tag (link_sel) */ bool playlist_outdated; -static int get_fid(const char *path); - static struct tag *tag_alloc(const char *path, const char *fname); static void tag_free(struct tag *tag); @@ -33,20 +30,13 @@ static int track_name_compare(struct link *a, struct link *b); static void tracks_load(struct tag *tag); static void tracks_save(struct tag *tag); -int -get_fid(const char *path) -{ - struct stat st; - return stat(path, &st) ? -1 : st.st_ino; -} - struct tag * tag_alloc(const char *path, const char *fname) { struct tag *tag; tag = malloc(sizeof(struct tag)); - if (!tag) err(1, "malloc"); + if (!tag) ERROR(SYSTEM, "malloc"); tag->fpath = aprintf("%s/%s", path, fname); tag->name = astrdup(fname); @@ -73,7 +63,7 @@ track_alloc(const char *dir, const char *fname) struct track *track; track = malloc(sizeof(struct track)); - if (!track) err(1, "malloc"); + if (!track) ERROR(SYSTEM, "malloc"); track->fpath = aprintf("%s/%s", dir, fname); track->name = astrdup(fname); @@ -118,7 +108,7 @@ tracks_load(struct tag *tag) if (file == NULL) { index_update(tag); /* create index */ file = fopen(index_path, "r"); - if (!file) err(1, "fopen %s", tag->name); + if (!file) ERROR(SYSTEM, "fopen %s", tag->name); } while (fgets(linebuf, sizeof(linebuf), file)) { @@ -145,10 +135,9 @@ tracks_save(struct tag *tag) /* write playlist back to index file */ index_path = aprintf("%s/index", tag->fpath); - file = fopen(index_path, "w+"); if (!file) { - fprintf(stderr, "Failed to write to index file: %s\n", + WARNX(SYSTEM, "Failed to write to index file: %s", index_path); free(index_path); return; @@ -284,12 +273,12 @@ index_update(struct tag *tag) DIR *dir; dir = opendir(tag->fpath); - if (!dir) ERROR("Failed to access dir: %s\n", tag->fpath); + if (!dir) ERROR(SYSTEM, "opendir %s", tag->fpath); index_path = aprintf("%s/index", tag->fpath); file = fopen(index_path, "w+"); - if (!file) ERROR("Failed to create index file in dir %s\n", tag->name); + if (!file) ERROR(SYSTEM, "fopen %s/index", tag->name); free(index_path); while ((ent = readdir(dir))) { @@ -622,13 +611,13 @@ data_load(void) list_init(&tags_sel); datadir = getenv("TMUS_DATA"); - if (!datadir) ERROR("TMUS_DATA not set!\n"); + if (!datadir) ERRORX(USER, "TMUS_DATA not set"); if (!acquire_lock(datadir)) - ERROR("Failed to acquire lock\n"); + ERRORX(USER, "Data directory in use"); dir = opendir(datadir); - if (!dir) ERROR("Failed to access dir: %s\n", datadir); + if (!dir) ERROR(SYSTEM, "opendir %s", datadir); while ((ent = readdir(dir))) { if (!strcmp(ent->d_name, ".")) @@ -637,12 +626,10 @@ data_load(void) continue; path = aprintf("%s/%s", datadir, ent->d_name); - if (!stat(path, &st) && S_ISDIR(st.st_mode)) { tag = tag_add(ent->d_name); tracks_load(tag); } - free(path); } diff --git a/src/history.c b/src/history.c @@ -3,7 +3,6 @@ #include "history.h" #include "util.h" -#include <err.h> #include <string.h> static struct inputln *history_list_prev( @@ -140,7 +139,7 @@ inputln_alloc(void) struct inputln *ln; ln = malloc(sizeof(struct inputln)); - if (!ln) err(1, "malloc"); + if (!ln) ERROR(SYSTEM, "malloc"); inputln_init(ln); return ln; @@ -160,7 +159,7 @@ inputln_resize(struct inputln *ln, size_t size) ln->cap = size; ln->buf = realloc(ln->buf, ln->cap * sizeof(char)); - if (!ln->buf) err(1, "realloc"); + if (!ln->buf) ERROR(SYSTEM, "realloc"); ln->len = MIN(ln->len, ln->cap-1); ln->buf[ln->len] = '\0'; } diff --git a/src/log.c b/src/log.c @@ -1,7 +1,6 @@ #include "log.h" #include "util.h" -#include <err.h> #include <stdbool.h> #include <stdlib.h> @@ -19,7 +18,7 @@ log_init(void) if (!envstr) return; log_file = fopen(envstr, "w+"); - if (!log_file) err(1, "fopen %s", envstr); + if (!log_file) ERROR(SYSTEM, "fopen %s", envstr); log_active = true; } @@ -47,3 +46,13 @@ log_info(const char *fmtstr, ...) fflush(log_file); } +void +log_infov(const char *fmtstr, va_list ap) +{ + if (!log_active) return; + + vfprintf(log_file, fmtstr, ap); + + fflush(log_file); +} + diff --git a/src/log.h b/src/log.h @@ -7,3 +7,4 @@ void log_init(void); void log_deinit(void); void log_info(const char *fmtstr, ...); +void log_infov(const char *fmtstr, va_list ap); diff --git a/src/mpris.c b/src/mpris.c @@ -3,7 +3,6 @@ #include "player.h" #include "util.h" -#include <err.h> #include <stdbool.h> static void dbus_handle_getall(DBusMessage *msg); @@ -98,7 +97,7 @@ dbus_init(void) ret = dbus_bus_request_name(dbus_conn, "org.mpris.MediaPlayer2.tmus", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if (dbus_error_is_set(&err)) - errx(1, "mpris register failed"); + ERRORX(SYSTEM, "mpris register failed"); log_info("DBus active!\n"); diff --git a/src/player.c b/src/player.c @@ -73,7 +73,7 @@ player_next_from_playlist(void) if (player.track && link_inuse(&player.track->link_pl)) { index = list_index(&player.playlist, &player.track->link_pl); - if (index < 0) PANIC(); + ASSERT(index >= 0); if (++index == list_len(&player.playlist)) return NULL; } else { diff --git a/src/player.h b/src/player.h @@ -3,8 +3,14 @@ #include "list.h" #include "util.h" +#define PLAYER_STATUS_INFO(...) \ + PLAYER_STATUS(PLAYER_STATUS_MSG_INFO, __VA_ARGS__) + +#define PLAYER_STATUS_ERR(...) \ + PLAYER_STATUS(PLAYER_STATUS_MSG_ERR, __VA_ARGS__) + #define PLAYER_STATUS(lvl, ...) do { \ - player.status_lvl = PLAYER_STATUS_MSG_ ## lvl; \ + player.status_lvl = (lvl); \ if (player.status) free(player.status); \ player.status = aprintf(__VA_ARGS__); \ } while (0) diff --git a/src/player_mpd.c b/src/player_mpd.c @@ -54,13 +54,13 @@ mpd_handle_status(int status) case MPD_ERROR_SERVER: case MPD_ERROR_ARGUMENT: if (!mpd_connection_clear_error(mpd.conn)) - ERROR("PLAYER: Failed to recover from argument error"); + ERRORX(SYSTEM, "Player failed to recover"); case MPD_ERROR_SYSTEM: errstr = mpd_connection_get_error_message(mpd.conn); - PLAYER_STATUS(ERR, "ERR - %s", errstr); + PLAYER_STATUS_ERR("ERR - %s", errstr); return false; case MPD_ERROR_CLOSED: - ERROR("PLAYER: Connection abruptly closed"); + ERRORX(SYSTEM, "Player connection abruptly closed"); } return true; @@ -128,12 +128,12 @@ player_update(void) if (!mpd.conn) { mpd.conn = mpd_connection_new(NULL, 0, 0); - if (!mpd.conn) ERROR("MPD: Connection failed\n"); + if (!mpd.conn) ERRX("MPD connection failed"); } status = mpd_run_status(mpd.conn); if (!status) { - PLAYER_STATUS(ERR, "MPD connection reset: %s", + PLAYER_STATUS_ERR("MPD connection reset: %s", mpd_connection_get_error_message(mpd.conn)); mpd_connection_free(mpd.conn); mpd.conn = NULL; @@ -158,7 +158,7 @@ player_update(void) * get status and track name again.. */ status = mpd_run_status(mpd.conn); if (!status) { - PLAYER_STATUS(ERR, "MPD connection reset: %s", + PLAYER_STATUS_ERR("MPD connection reset: %s", mpd_connection_get_error_message(mpd.conn)); mpd_connection_free(mpd.conn); mpd.conn = NULL; @@ -192,7 +192,7 @@ player_update(void) player.state = PLAYER_STATE_STOPPED; break; default: - PANIC(); + ASSERT(0); } player.volume = mpd_status_get_volume(status); @@ -317,7 +317,7 @@ player_seek(int sec) player_clear_status(); if (!player.loaded || player.state == PLAYER_STATE_STOPPED) { - PLAYER_STATUS(ERR, "No track loaded"); + PLAYER_STATUS_ERR("No track loaded"); return PLAYER_STATUS_ERR; } @@ -338,7 +338,7 @@ player_set_volume(unsigned int vol) player_clear_status(); if (player.volume == -1) { - PLAYER_STATUS(ERR, "Volume control not supported"); + PLAYER_STATUS_ERR("Volume control not supported"); return PLAYER_STATUS_ERR; } diff --git a/src/player_mplay.c b/src/player_mplay.c @@ -8,7 +8,6 @@ #include <sys/wait.h> #include <sys/mman.h> #include <unistd.h> -#include <err.h> #include <errno.h> #include <signal.h> #include <stdbool.h> @@ -57,23 +56,23 @@ mplay_run(struct track *track) ASSERT(!player.loaded); if (pipe(input) == -1) - err(1, "pipe"); + ERROR(SYSTEM, "pipe"); if (pipe(output) == -1) - err(1, "pipe"); + ERROR(SYSTEM, "pipe"); mplay.pid = fork(); - if (mplay.pid < 0) err(1, "fork"); + if (mplay.pid < 0) ERROR(SYSTEM, "fork"); if (mplay.pid != 0) { close(output[1]); mplay.stdout = fdopen(output[0], "r"); - if (!mplay.stdout) err(1, "fdopen"); + if (!mplay.stdout) ERROR(SYSTEM, "fdopen"); setvbuf(mplay.stdout, NULL, _IONBF, 0); close(input[0]); mplay.stdin = fdopen(input[1], "w"); - if (!mplay.stdin) err(1, "fdopen"); + if (!mplay.stdin) ERROR(SYSTEM, "fdopen"); setvbuf(mplay.stdin, NULL, _IONBF, 0); } else { close(0); @@ -93,7 +92,7 @@ mplay_run(struct track *track) line = mplay_readline(); if (!line || strcmp(line, "+READY")) { mplay_kill(); - PLAYER_STATUS(ERR, "Failed to start"); + PLAYER_STATUS_ERR("Failed to start"); return false; } @@ -200,7 +199,7 @@ player_update(void) line = mplay_readline(); if (!player.loaded) return; if (!line || strncmp(line, "+STATUS:", 8)) { - PLAYER_STATUS(ERR, "Bad response"); + PLAYER_STATUS_ERR("Bad response"); return; } @@ -259,7 +258,7 @@ player_toggle_pause(void) fprintf(mplay.stdin, "pause\n"); line = mplay_readline(); if (!line || strncmp(line, "+PAUSE:", 7)) { - PLAYER_STATUS(ERR, "Bad response"); + PLAYER_STATUS_ERR("Bad response"); return PLAYER_STATUS_ERR; } @@ -308,7 +307,7 @@ player_seek(int sec) fprintf(mplay.stdin, "seek %i\n", sec); line = mplay_readline(); if (!line || strncmp(line, "+SEEK:", 6)) { - PLAYER_STATUS(ERR, "Bad response"); + PLAYER_STATUS_ERR("Bad response"); return PLAYER_STATUS_ERR; } @@ -326,14 +325,14 @@ player_set_volume(unsigned int vol) player_clear_status(); if (player.volume == -1) { - PLAYER_STATUS(ERR, "Volume control not supported"); + PLAYER_STATUS_ERR("Volume control not supported"); return PLAYER_STATUS_ERR; } fprintf(mplay.stdin, "vol %i\n", vol); line = mplay_readline(); if (!line || strncmp(line, "+VOLUME:", 8)) { - PLAYER_STATUS(ERR, "Bad response"); + PLAYER_STATUS_ERR("Bad response"); return PLAYER_STATUS_ERR; } diff --git a/src/ref.c b/src/ref.c @@ -1,15 +1,13 @@ #include "ref.h" #include "util.h" -#include <err.h> - struct ref * ref_alloc(void *data) { struct ref *ref; ref = malloc(sizeof(struct ref)); - if (!ref) err(1, "malloc"); + if (!ref) ERROR(SYSTEM, "malloc"); ref->link = LINK_EMPTY; ref->data = data; diff --git a/src/strbuf.c b/src/strbuf.c @@ -2,7 +2,6 @@ #include "util.h" -#include <err.h> #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -42,13 +41,13 @@ strbuf_append(struct strbuf *strbuf, const char *fmt, ...) va_start(cpy, fmt); slen = vsnprintf(NULL, 0, fmt, cpy); - if (slen < 0) err(1, "snprintf"); + if (slen < 0) ERROR(SYSTEM, "snprintf"); va_end(cpy); if (blen + slen + 1 > strbuf->cap) { strbuf->cap = blen + slen + 1; strbuf->buf = realloc(strbuf->buf, strbuf->cap); - if (strbuf->buf) err(1, "realloc"); + if (!strbuf->buf) ERROR(SYSTEM, "realloc"); } va_start(ap, fmt); diff --git a/src/tui.c b/src/tui.c @@ -1,3 +1,4 @@ +#include <stdbool.h> #define NCURSES_WIDECHAR 1 #define _GNU_SOURCE @@ -1290,11 +1291,3 @@ tui_update(void) return !quit; } - -void -tui_restore(void) -{ - if (!isendwin()) - endwin(); -} - diff --git a/src/tui.h b/src/tui.h @@ -14,9 +14,7 @@ void tui_init(void); void tui_deinit(void); - bool tui_update(void); -void tui_restore(void); extern struct pane *cmd_pane, *tag_pane, *track_pane; extern struct pane *pane_sel, *pane_after_cmd; @@ -30,3 +28,15 @@ extern struct listnav track_nav; extern char *cmd_status; extern int cmd_status_uptime; +static inline bool +tui_enabled(void) +{ + return !isendwin(); +} + +static inline void +tui_restore(void) +{ + if (!isendwin()) + endwin(); +} diff --git a/src/util.c b/src/util.c @@ -1,11 +1,13 @@ +#include <stdio.h> #define _XOPEN_SOURCE 600 #define _GNU_SOURCE -#include "util.h" #include "tui.h" +#include "util.h" +#include "log.h" #include <execinfo.h> -#include <err.h> +#include <errno.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -18,15 +20,16 @@ panic(const char *file, int line, const char *msg, ...) { va_list ap; - tui_restore(); + if (tui_enabled()) + tui_restore(); - fprintf(stderr, "Panic at %s:%i (", file, line); va_start(ap, msg); + fprintf(stderr, "tmus: panic at %s:%i (", file, line); vfprintf(stderr, msg, ap); - va_end(ap); fprintf(stderr, ")\n"); + va_end(ap); - exit(1); + abort(); } void @@ -34,25 +37,60 @@ assert(int cond, const char *file, int line, const char *condstr) { if (cond) return; - tui_restore(); + if (tui_enabled()) + tui_restore(); + + fprintf(stderr, "tmus: assertion failed %s:%i (%s)\n", + file, line, condstr); + + abort(); +} - fprintf(stderr, "Assertion failed %s:%i (%s)\n", file, line, condstr); +void +warn(bool add_error, int type, const char *fmtstr, ...) +{ + va_list ap; - exit(1); + va_start(ap, fmtstr); + if (tui_enabled()) { + if (type != USER) + log_info("tmus: "); + log_infov(fmtstr, ap); + if (add_error) + log_info(": %s", strerror(errno)); + log_info("\n"); + } else { + if (type != USER) + fprintf(stderr, "tmus: "); + vfprintf(stderr, fmtstr, ap); + if (add_error) + fprintf(stderr, ": %s", strerror(errno)); + fprintf(stderr, "\n"); + } + va_end(ap); } void -error(const char *fmtstr, ...) +error(bool add_error, int type, const char *fmtstr, ...) { va_list ap; - tui_restore(); + if (tui_enabled()) + tui_restore(); va_start(ap, fmtstr); + if (type != USER) + fprintf(stderr, "tmus: "); vfprintf(stderr, fmtstr, ap); + if (add_error) + fprintf(stderr, ": %s", strerror(errno)); + fprintf(stderr, "\n"); va_end(ap); - exit(1); + if (type == INTERNAL) + abort(); + else + exit(1); } char * @@ -61,7 +99,7 @@ astrdup(const char *str) char *alloc; alloc = strdup(str); - if (!alloc) err(1, "strdup"); + if (!alloc) ERROR(SYSTEM, "strdup"); return alloc; } @@ -77,11 +115,11 @@ aprintf(const char *fmtstr, ...) va_start(ap, fmtstr); size = vsnprintf(NULL, 0, fmtstr, ap); - if (size < 0) err(1, "snprintf"); + if (size < 0) ERROR(SYSTEM, "snprintf"); va_end(ap); str = malloc(size + 1); - if (!str) err(1, "malloc"); + if (!str) ERROR(SYSTEM, "malloc"); va_start(cpy, fmtstr); vsnprintf(str, size + 1, fmtstr, cpy); @@ -104,7 +142,7 @@ appendstrf(char *alloc, const char *fmtstr, ...) prevlen = alloc ? strlen(alloc) : 0; alloc = realloc(alloc, prevlen + size + 1); - if (!alloc) return NULL; + if (!alloc) ERROR(SYSTEM, "realloc"); va_start(cpy, fmtstr); vsnprintf(alloc + prevlen, size + 1, fmtstr, cpy); diff --git a/src/util.h b/src/util.h @@ -1,5 +1,6 @@ #pragma once +#include <stdbool.h> #include <stdio.h> #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -8,13 +9,23 @@ #define PANIC(...) panic(__FILE__, __LINE__, "" __VA_ARGS__) #define ASSERT(x) assert((x), __FILE__, __LINE__, #x) -#define ERROR(...) error("" __VA_ARGS__) +#define WARNX(...) warn(false, __VA_ARGS__); +#define WARN(...) warn(true, __VA_ARGS__); +#define ERRORX(...) error(false, __VA_ARGS__); +#define ERROR(...) error(true, __VA_ARGS__); #define UPCAST(iter, type, link) LINK_UPCAST(iter, type, link) +enum { + USER, + SYSTEM, + INTERNAL +}; + void panic(const char *file, int line, const char *msg, ...); void assert(int cond, const char *file, int line, const char *condstr); -void error(const char *fmtstr, ...); +void warn(bool add_error, int type, const char *fmtstr, ...); +void error(bool add_error, int type, const char *fmtstr, ...); char *astrdup(const char *str); char *aprintf(const char *fmtstr, ...);