From e184c8bf911bed6a89528ebe210fa1d069560f21 Mon Sep 17 00:00:00 2001 From: ec429 Date: Fri, 2 Mar 2012 15:46:51 +0000 Subject: [PATCH] Ring-buffer for debug messages. Complicated (see full message). When debugging is disabled, messages with a prio of DEBUG get stored in d_buf, which is a ring buffer of 64 lines; on enabling debugging, the contents of this buffer are flushed to the (status) tab. Consequently, if something strange happens and you want to debug it, you can read all the debugging info about what just happened; but all that debugging info won't fill up buf 0 and cause visible messages to disappear from the (status) tab when debugging is disabled. --- buffer.c | 144 ++++++++++++++++++++++++++++-------------------- buffer.h | 22 +++++--- config.c | 28 +++++----- config_check.c | 16 +++--- config_rcread.c | 24 ++++---- genconfig.c | 8 +-- input.c | 11 +++- quirc.c | 35 ++++++------ 8 files changed, 165 insertions(+), 123 deletions(-) diff --git a/buffer.c b/buffer.c index 4c47e42..4c4d9d4 100644 --- a/buffer.c +++ b/buffer.c @@ -8,75 +8,79 @@ #include "buffer.h" -int init_start_buffer(void) +int init_ring(ring *r) { - s_buf.nlines=0; - s_buf.lt=NULL; - s_buf.lm=NULL; - s_buf.ts=NULL; - s_buf.errs=0; + r->nlines=64; + r->ptr=0; + r->filled=false; + r->loop=false; + r->lt=malloc(r->nlines*sizeof(char *)); + r->ltag=malloc(r->nlines*sizeof(char *)); + r->lm=malloc(r->nlines*sizeof(mtype)); + r->ts=malloc(r->nlines*sizeof(time_t)); + r->errs=0; return(0); } -int add_to_start_buffer(mtype lm, const char *lt) +int add_to_ring(ring *r, mtype lm, const char *lt, const char *ltag) { - s_buf.nlines++; - char **nlt;mtype *nlm;time_t *nts; - nlt=(char **)realloc(s_buf.lt, s_buf.nlines*sizeof(char *)); - if(!nlt) + if(!r->nlines) init_ring(r); + int p=r->ptr; + if(!(++r->ptrnlines)) { - s_buf.nlines--; - s_buf.errs++; - return(1); - } - s_buf.lt=nlt; - s_buf.lt[s_buf.nlines-1]=strdup(lt); - nlm=(mtype *)realloc(s_buf.lm, s_buf.nlines*sizeof(mtype)); - if(!nlm) - { - s_buf.nlines--; - s_buf.errs++; - return(1); - } - s_buf.lm=nlm; - s_buf.lm[s_buf.nlines-1]=lm; - nts=(time_t *)realloc(s_buf.ts, s_buf.nlines*sizeof(time_t)); - if(!nts) - { - s_buf.nlines--; - s_buf.errs++; - return(1); + if(r->loop) + { + r->filled=true; + r->ptr-=r->nlines; + } + else + { + r->ptr=p; + r->errs++; + return(1); + } } - s_buf.ts=nts; - s_buf.ts[s_buf.nlines-1]=time(NULL); + r->lt[p]=strdup(lt); + r->ltag[p]=strdup(ltag); + r->lm[p]=lm; + r->ts[p]=time(NULL); return(0); } -int asb_failsafe(mtype lm, const char *lt) +int atr_failsafe(ring *r, mtype lm, const char *lt, const char *ltag) { int e=0; - if((e=add_to_start_buffer(lm, lt))) + if((e=add_to_ring(r, lm, lt, ltag))) { - fprintf(stderr, "init[%d]: %s\n", e, lt); + fprintf(stderr, "atr[%d]: %s%s\n", e, ltag, lt); } return(e); } -int free_start_buffer(void) +int free_ring(ring *r) { int i; - if(s_buf.lt) + if(r->lt) + { + for(i=0;i<(r->filled?r->nlines:r->ptr);i++) + { + free(r->lt[i]); + } + free(r->lt); + r->lt=NULL; + } + if(r->ltag) { - for(i=0;ifilled?r->nlines:r->ptr);i++) { - free(s_buf.lt[i]); + free(r->ltag[i]); } - free(s_buf.lt); - s_buf.lt=NULL; + free(r->ltag); + r->ltag=NULL; } - free(s_buf.lm); - free(s_buf.ts); - s_buf.nlines=0; + free(r->lm); + free(r->ts); + r->nlines=0; return(0); } @@ -92,6 +96,8 @@ int initialise_buffers(int buflines) bufs[0].nick=nick; bufs[0].ilist=igns; add_to_buffer(0, STA, QUIET, 0, false, GPL_TAIL, "quirc -- "); + init_ring(&d_buf); + d_buf.loop=true; return(0); } @@ -257,6 +263,15 @@ int add_to_buffer(int buf, mtype lm, prio lq, char lp, bool ls, const char *lt, } return(1); } + if(!debug&&(lq==DEBUG)) + { + if(!d_buf.nlines) + { + init_ring(&d_buf); + d_buf.loop=true; + } + return(add_to_ring(&d_buf, lm, lt, ltag)); + } int optr=bufs[buf].ptr; bool scrollisptr=(bufs[buf].scroll==bufs[buf].ptr)&&(bufs[buf].ascroll==0); bufs[buf].lm[bufs[buf].ptr]=lm; @@ -936,40 +951,51 @@ int e_buf_print(int buf, mtype lm, message pkt, const char *lead) return(add_to_buffer(buf, lm, QUIET, 0, false, text, lead)); } -int transfer_start_buffer(void) +int transfer_ring(ring *r, prio lq) { int i,e=0; - for(i=0;ifilled) { - e|=add_to_buffer(0, s_buf.lm[i], QUIET, 0, false, s_buf.lt[i], "init: "); + for(i=0;inlines;i++) + { + int j=(i+r->ptr)%r->nlines; + e|=add_to_buffer(0, r->lm[j], lq, 0, false, r->lt[j], r->ltag[j]); + } + } + else + { + for(i=0;iptr;i++) + { + e|=add_to_buffer(0, r->lm[i], lq, 0, false, r->lt[i], r->ltag[i]); + } } return(e); } -int push_buffer(void) +int push_ring(ring *r, prio lq) { - if(!bufs || transfer_start_buffer()) + if(!bufs || transfer_ring(r, lq)) { - if(bufs) add_to_buffer(0, ERR, NORMAL, 0, false, "Failed to transfer start_buffer", "init[xsb]: "); + if(bufs) add_to_buffer(0, ERR, NORMAL, 0, false, "Failed to transfer ring", "init[xr]: "); int i; - for(i=0;iltag[i], r->lt[i]); } if(bufs) { char msg[32]; - sprintf(msg, "%d messages written to stderr", s_buf.nlines); - add_to_buffer(0, STA, NORMAL, 0, false, msg, "init[xsb]: "); + sprintf(msg, "%d messages written to stderr", r->nlines); + add_to_buffer(0, STA, NORMAL, 0, false, msg, "init[xr]: "); } } - if(bufs&&s_buf.errs) + if(bufs&&r->errs) { char msg[80]; - sprintf(msg, "%d messages were written to stderr due to start_buffer errors", s_buf.errs); + sprintf(msg, "%d messages were written to stderr due to ring errors", r->errs); add_to_buffer(0, ERR, NORMAL, 0, false, msg, "init[errs]: "); } - return(free_start_buffer()); + return(free_ring(r)); } void titlebar(void) diff --git a/buffer.h b/buffer.h index 410d6f4..51e4ec8 100644 --- a/buffer.h +++ b/buffer.h @@ -113,20 +113,26 @@ int nbufs; int cbuf; buffer *bufs; -struct +typedef struct { int nlines; + int ptr; + bool filled; char **lt; + char **ltag; mtype *lm; time_t *ts; + bool loop; int errs; } -s_buf; +ring; -int init_start_buffer(void); -int add_to_start_buffer(mtype lm, const char *lt); -int asb_failsafe(mtype lm, const char *lt); -int free_start_buffer(void); +ring s_buf, d_buf; + +int init_ring(ring *r); +int add_to_ring(ring *r, mtype lm, const char *lt, const char *ltag); +int atr_failsafe(ring *r, mtype lm, const char *lt, const char *ltag); +int free_ring(ring *r); int initialise_buffers(int buflines); int init_buffer(int buf, btype type, const char *bname, int nlines); int free_buffer(int buf); @@ -136,8 +142,8 @@ int redraw_buffer(void); int render_buffer(int buf); int render_line(int buf, int uline); int e_buf_print(int buf, mtype lm, message pkt, const char *lead); -int transfer_start_buffer(void); -int push_buffer(void); +int transfer_ring(ring *r, prio lq); +int push_ring(ring *r, prio lq); void in_update(iline inp); char *highlight(const char *src); // use colours to highlight \escapes. Returns a malloc-like pointer void titlebar(void); diff --git a/config.c b/config.c index 8eb8e0e..af3caf1 100644 --- a/config.c +++ b/config.c @@ -27,7 +27,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: missing mod in %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); free(line); continue; } @@ -36,7 +36,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: odd mod length in %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); free(line); continue; } @@ -45,7 +45,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: malloc failure in %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); free(line); continue; } @@ -56,7 +56,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: bad mod (not hex) in %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); free(line); cont=true; break; @@ -67,7 +67,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: sscanf failed in %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); free(line); cont=true; break; @@ -90,7 +90,7 @@ void loadkeys(FILE *fp) { char msg[32+strlen(new.name)]; sprintf(msg, "keys: unrecognised name %s", new.name); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); } free(new.mod); } @@ -217,7 +217,7 @@ int rcread(FILE *rcfp) { char msg[48+strlen(cmd)]; sprintf(msg, "rc: Unrecognised ident in %%colour (%s)", cmd); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); nerrors++; } } @@ -230,7 +230,7 @@ int rcread(FILE *rcfp) { char msg[40+strlen(cmd)]; sprintf(msg, "rc: Command (%s) without argument", cmd); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); nerrors++; } else if(strcmp(cmd, "server")==0) @@ -296,7 +296,7 @@ int rcread(FILE *rcfp) char *sw=strtok(rest, " \t"); if(*sw!='-') { - asb_failsafe(ERR, "rc: ignore: need options (use '-' for no options)"); + atr_failsafe(&s_buf, ERR, "rc: ignore: need options (use '-' for no options)", "init: "); nerrors++; } else @@ -304,7 +304,7 @@ int rcread(FILE *rcfp) rest=strtok(NULL, ""); if(!rest) { - asb_failsafe(ERR, "rc: ignore: need options (use '-' for no options)"); + atr_failsafe(&s_buf, ERR, "rc: ignore: need options (use '-' for no options)", "init: "); nerrors++; } else @@ -346,7 +346,7 @@ int rcread(FILE *rcfp) char *sw=strtok(rest, " \t"); if(*sw!='-') { - asb_failsafe(ERR, "rc: *ignore: need options (use '-' for no options)"); + atr_failsafe(&s_buf, ERR, "rc: *ignore: need options (use '-' for no options)", "init: "); nerrors++; } else @@ -354,7 +354,7 @@ int rcread(FILE *rcfp) rest=strtok(NULL, ""); if(!rest) { - asb_failsafe(ERR, "rc: *ignore: need options (use '-' for no options)"); + atr_failsafe(&s_buf, ERR, "rc: *ignore: need options (use '-' for no options)", "init: "); nerrors++; } else @@ -411,7 +411,7 @@ int rcread(FILE *rcfp) { char msg[48+strlen(cmd)]; sprintf(msg, "rc: Unrecognised cmd %s in .quirc (ignoring)", cmd); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); nerrors++; } } @@ -510,7 +510,7 @@ signed int pargs(int argc, char *argv[]) { char msg[40+strlen(argv[arg])]; sprintf(msg, "pargs: Unrecognised argument '%s'", argv[arg]); - asb_failsafe(ERR, msg); + atr_failsafe(&s_buf, ERR, msg, "init: "); } } if(check) return(0); diff --git a/config_check.c b/config_check.c index d5f0379..d068eac 100644 --- a/config_check.c +++ b/config_check.c @@ -3,42 +3,42 @@ int conf_check(void) { if(width<30) { - asb_failsafe(STA, "width set to minimum 30"); + atr_failsafe(&s_buf, STA, "width set to minimum 30", "init: "); width=30; } if(height<5) { - asb_failsafe(STA, "height set to minimum 5"); + atr_failsafe(&s_buf, STA, "height set to minimum 5", "init: "); height=5; } if(mirc_colour_compat>2) { - asb_failsafe(STA, "mcc set to maximum 2"); + atr_failsafe(&s_buf, STA, "mcc set to maximum 2", "init: "); mirc_colour_compat=2; } if(force_redraw>3) { - asb_failsafe(STA, "fred set to maximum 3"); + atr_failsafe(&s_buf, STA, "fred set to maximum 3", "init: "); force_redraw=3; } if(buflines<32) { - asb_failsafe(STA, "buf set to minimum 32"); + atr_failsafe(&s_buf, STA, "buf set to minimum 32", "init: "); buflines=32; } if(maxnlen<4) { - asb_failsafe(STA, "mnln set to minimum 4"); + atr_failsafe(&s_buf, STA, "mnln set to minimum 4", "init: "); maxnlen=4; } if(tping<15) { - asb_failsafe(STA, "tping set to minimum 15"); + atr_failsafe(&s_buf, STA, "tping set to minimum 15", "init: "); tping=15; } if(ts>6) { - asb_failsafe(STA, "ts set to maximum 6"); + atr_failsafe(&s_buf, STA, "ts set to maximum 6", "init: "); ts=6; } return(0); diff --git a/config_rcread.c b/config_rcread.c index 4909fc0..d936f9f 100644 --- a/config_rcread.c +++ b/config_rcread.c @@ -8,8 +8,8 @@ mirc_colour_compat=value; else { - asb_failsafe(ERR, "Malformed rc entry for mcc (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for mcc (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "no-fred")==0) @@ -21,8 +21,8 @@ force_redraw=value; else { - asb_failsafe(ERR, "Malformed rc entry for fred (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for fred (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "buf")==0) @@ -32,8 +32,8 @@ buflines=value; else { - asb_failsafe(ERR, "Malformed rc entry for buf (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for buf (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "mnln")==0) @@ -43,8 +43,8 @@ maxnlen=value; else { - asb_failsafe(ERR, "Malformed rc entry for mnln (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for mnln (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "no-fwc")==0) @@ -84,8 +84,8 @@ tping=value; else { - asb_failsafe(ERR, "Malformed rc entry for tping (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for tping (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "no-ts")==0) @@ -97,8 +97,8 @@ ts=value; else { - asb_failsafe(ERR, "Malformed rc entry for ts (value not numeric)"); - asb_failsafe(ERR, rest); + atr_failsafe(&s_buf, ERR, "Malformed rc entry for ts (value not numeric)", "init: "); + atr_failsafe(&s_buf, ERR, rest, "init: "); } } else if(strcmp(cmd, "no-utc")==0) diff --git a/genconfig.c b/genconfig.c index 31a1658..2ce1047 100644 --- a/genconfig.c +++ b/genconfig.c @@ -376,11 +376,11 @@ Generated by genconfig\n\ case INT: if(ents[i].min>0) { - printf("\tif(%s<%d)\n\t{\n\t\tasb_failsafe(STA, \"%s set to minimum %d\");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].min, ents[i].set_name, ents[i].min, ents[i].cname, ents[i].min); + printf("\tif(%s<%d)\n\t{\n\t\tatr_failsafe(&s_buf, STA, \"%s set to minimum %d\", \"init: \");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].min, ents[i].set_name, ents[i].min, ents[i].cname, ents[i].min); } if(ents[i].max!=-1) { - printf("\tif(%s>%d)\n\t{\n\t\tasb_failsafe(STA, \"%s set to maximum %d\");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].max, ents[i].set_name, ents[i].max, ents[i].cname, ents[i].max); + printf("\tif(%s>%d)\n\t{\n\t\tatr_failsafe(&s_buf, STA, \"%s set to maximum %d\", \"init: \");\n\t\t%s=%d;\n\t}\n", ents[i].cname, ents[i].max, ents[i].set_name, ents[i].max, ents[i].cname, ents[i].max); } break; case BOOL: @@ -416,8 +416,8 @@ Generated by genconfig\n\ else { printf("\t\t\t\t{\n"); - printf("\t\t\t\t\tasb_failsafe(ERR, \"Malformed rc entry for %s (value not numeric)\");\n", ents[i].rc_name); - printf("\t\t\t\t\tasb_failsafe(ERR, rest);\n"); + printf("\t\t\t\t\tatr_failsafe(&s_buf, ERR, \"Malformed rc entry for %s (value not numeric)\", \"init: \");\n", ents[i].rc_name); + printf("\t\t\t\t\tatr_failsafe(&s_buf, ERR, rest, \"init: \");\n"); printf("\t\t\t\t}\n"); } printf("\t\t\t}\n"); diff --git a/input.c b/input.c index b5eb4ca..cc50abb 100644 --- a/input.c +++ b/input.c @@ -567,7 +567,7 @@ int cmd_handle(char *inp, char **qmsg, fd_set *master, int *fdmax) // old state= } if(strcmp(cmd, "set")==0) // set options { - bool osp=show_prefix; + bool osp=show_prefix, odbg=debug; unsigned int omln=maxnlen; if(args) { @@ -669,6 +669,15 @@ int cmd_handle(char *inp, char **qmsg, fd_set *master, int *fdmax) // old state= for(int b=0;b=0) { - push_buffer(); + push_ring(&s_buf, QUIET); return(e); } @@ -152,8 +153,8 @@ int main(int argc, char *argv[]) if(ttyraw(fileno(stdout))) { - asb_failsafe(ERR, "Failed to set raw mode on tty: ttyraw:"); - asb_failsafe(ERR, strerror(errno)); + atr_failsafe(&s_buf, ERR, "Failed to set raw mode on tty: ttyraw:", "init: "); + atr_failsafe(&s_buf, ERR, strerror(errno), "init: "); } unsigned int i; @@ -164,11 +165,11 @@ int main(int argc, char *argv[]) if(e) { fprintf(stderr, "Failed to set up buffers\n"); - push_buffer(); + push_ring(&s_buf, QUIET); return(1); } - push_buffer(); + push_ring(&s_buf, QUIET); fd_set master, readfds; FD_ZERO(&master);