scan-build false positive workarounds #624

Eliminate scan-build false positive about garbage value
in conditional by replacing a malloc+manual init with a
calloc() #624. The other error it has been reporting goes
away with -maxloop=1000, so I think we're fine now.

Also, simplify paint() by dumping the lfdimx parameter, which
is always the same thing as dstlenx (we originally wrote this
with different resizing semantics). Update callers.
This commit is contained in:
nick black 2020-08-10 01:07:10 -04:00
parent 5b432c6d94
commit e0bb0607a0
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 22 additions and 14 deletions

View File

@ -65,6 +65,9 @@ typedef struct ncplane {
cell* fb; // "framebuffer" of character cells cell* fb; // "framebuffer" of character cells
int logrow; // logical top row, starts at 0, add one for each scroll int logrow; // logical top row, starts at 0, add one for each scroll
int x, y; // current cursor location within this plane int x, y; // current cursor location within this plane
// ncplane_yx() etc. use coordinates relative to the plane to which this
// plane is bound, but absx/absy are always relative to the terminal origin.
// they must thus be translated by any such function.
int absx, absy; // origin of the plane relative to the screen int absx, absy; // origin of the plane relative to the screen
int lenx, leny; // size of the plane, [0..len{x,y}) is addressable int lenx, leny; // size of the plane, [0..len{x,y}) is addressable
struct ncplane* above; // plane above us, NULL if we're on top struct ncplane* above; // plane above us, NULL if we're on top

View File

@ -247,17 +247,25 @@ lock_in_highcontrast(cell* targc, struct crender* crender){
} }
} }
// Paints a single ncplane into the provided scratch framebuffer 'fb', and // Paints a single ncplane 'p' into the provided scratch framebuffer 'fb', and
// ultimately 'lastframe' (we can't always write directly into 'lastframe', // ultimately 'lastframe' (we can't always write directly into 'lastframe',
// because we need build state to solve certain cells, and need compare their // because we need build state to solve certain cells, and need compare their
// solved result to the last frame). Whenever a cell is locked in, it is // solved result to the last frame). Whenever a cell is locked in, it is
// compared against the last frame. If it is different, the 'rvec' bitmap is // compared against the last frame. If it is different, the 'rvec' bitmap is
// updated with a 1. 'pool' is typically nc->pool, but should be whatever's // updated with a 1. 'pool' is typically nc->pool, but should be whatever's
// backing fb. // backing fb.
//
// dstleny: leny of target rendering area described by fb/lastframe
// dstlenx: lenx of target rendering area described by fb
// dstabsy: absy of target rendering area (relative to terminal)
// dstabsx: absx of target rendering area (relative to terminal)
//
// only those cells where 'p' intersects with the target rendering area are
// rendered.
static int static int
paint(ncplane* p, cell* lastframe, struct crender* rvec, paint(ncplane* p, cell* lastframe, struct crender* rvec,
cell* fb, egcpool* pool, int dstleny, int dstlenx, cell* fb, egcpool* pool, int dstleny, int dstlenx,
int dstabsy, int dstabsx, int lfdimx){ int dstabsy, int dstabsx){
int y, x, dimy, dimx, offy, offx; int y, x, dimy, dimx, offy, offx;
ncplane_dim_yx(p, &dimy, &dimx); ncplane_dim_yx(p, &dimy, &dimx);
offy = p->absy - dstabsy; offy = p->absy - dstabsy;
@ -278,12 +286,12 @@ paint(ncplane* p, cell* lastframe, struct crender* rvec,
for(y = starty ; y < dimy ; ++y){ for(y = starty ; y < dimy ; ++y){
const int absy = y + offy; const int absy = y + offy;
// once we've passed the physical screen's bottom, we're done // once we've passed the physical screen's bottom, we're done
if(absy >= dstleny){ if(absy >= dstleny || absy < 0){
break; break;
} }
for(x = startx ; x < dimx ; ++x){ for(x = startx ; x < dimx ; ++x){
const int absx = x + offx; const int absx = x + offx;
if(absx >= dstlenx){ if(absx >= dstlenx || absx < 0){
break; break;
} }
cell* targc = &fb[fbcellidx(absy, dstlenx, absx)]; cell* targc = &fb[fbcellidx(absy, dstlenx, absx)];
@ -371,7 +379,7 @@ paint(ncplane* p, cell* lastframe, struct crender* rvec,
// which were already locked in were skipped at the top of the loop)? // which were already locked in were skipped at the top of the loop)?
if(cell_locked_p(targc)){ if(cell_locked_p(targc)){
lock_in_highcontrast(targc, crender); lock_in_highcontrast(targc, crender);
cell* prevcell = &lastframe[fbcellidx(absy, lfdimx, absx)]; cell* prevcell = &lastframe[fbcellidx(absy, dstlenx, absx)];
/*if(cell_simple_p(targc)){ /*if(cell_simple_p(targc)){
fprintf(stderr, "WROTE %u [%c] to %d/%d (%d/%d)\n", targc->gcluster, targc->gcluster, y, x, absy, absx); fprintf(stderr, "WROTE %u [%c] to %d/%d (%d/%d)\n", targc->gcluster, targc->gcluster, y, x, absy, absx);
}else{ }else{
@ -406,9 +414,6 @@ init_fb(cell* fb, int dimy, int dimx){
for(int y = 0 ; y < dimy ; ++y){ for(int y = 0 ; y < dimy ; ++y){
for(int x = 0 ; x < dimx ; ++x){ for(int x = 0 ; x < dimx ; ++x){
cell* c = &fb[fbcellidx(y, dimx, x)]; cell* c = &fb[fbcellidx(y, dimx, x)];
c->gcluster = 0;
c->channels = 0;
c->attrword = 0;
cell_set_fg_alpha(c, CELL_ALPHA_TRANSPARENT); cell_set_fg_alpha(c, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(c, CELL_ALPHA_TRANSPARENT); cell_set_bg_alpha(c, CELL_ALPHA_TRANSPARENT);
} }
@ -442,22 +447,22 @@ int ncplane_mergedown(ncplane* restrict src, ncplane* restrict dst){
} }
int dimy, dimx; int dimy, dimx;
ncplane_dim_yx(dst, &dimy, &dimx); ncplane_dim_yx(dst, &dimy, &dimx);
cell* tmpfb = malloc(sizeof(*tmpfb) * dimy * dimx); cell* tmpfb = calloc(sizeof(*tmpfb), dimy * dimx);
cell* rendfb = malloc(sizeof(*rendfb) * dimy * dimx); cell* rendfb = calloc(sizeof(*rendfb), dimy * dimx);
const size_t crenderlen = sizeof(struct crender) * dimy * dimx; const size_t crenderlen = sizeof(struct crender) * dimy * dimx;
struct crender* rvec = malloc(crenderlen); struct crender* rvec = malloc(crenderlen);
memset(rvec, 0, crenderlen); memset(rvec, 0, crenderlen);
init_fb(tmpfb, dimy, dimx); init_fb(tmpfb, dimy, dimx);
init_fb(rendfb, dimy, dimx); init_fb(rendfb, dimy, dimx);
if(paint(src, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx, if(paint(src, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx,
dst->absy, dst->absx, dst->lenx)){ dst->absy, dst->absx)){
free(rvec); free(rvec);
free(rendfb); free(rendfb);
free(tmpfb); free(tmpfb);
return -1; return -1;
} }
if(paint(dst, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx, if(paint(dst, rendfb, rvec, tmpfb, &dst->pool, dst->leny, dst->lenx,
dst->absy, dst->absx, dst->lenx)){ dst->absy, dst->absx)){
free(rvec); free(rvec);
free(rendfb); free(rendfb);
free(tmpfb); free(tmpfb);
@ -1029,13 +1034,13 @@ static int
notcurses_render_internal(notcurses* nc, struct crender* rvec){ notcurses_render_internal(notcurses* nc, struct crender* rvec){
int dimy, dimx; int dimy, dimx;
ncplane_dim_yx(nc->stdplane, &dimy, &dimx); ncplane_dim_yx(nc->stdplane, &dimy, &dimx);
cell* fb = malloc(sizeof(*fb) * dimy * dimx); cell* fb = calloc(sizeof(*fb), dimy * dimx);
init_fb(fb, dimy, dimx); init_fb(fb, dimy, dimx);
ncplane* p = nc->top; ncplane* p = nc->top;
while(p){ while(p){
if(paint(p, nc->lastframe, rvec, fb, &nc->pool, if(paint(p, nc->lastframe, rvec, fb, &nc->pool,
nc->stdplane->leny, nc->stdplane->lenx, nc->stdplane->leny, nc->stdplane->lenx,
nc->stdplane->absy, nc->stdplane->absx, nc->lfdimx)){ nc->stdplane->absy, nc->stdplane->absx)){
free(fb); free(fb);
return -1; return -1;
} }