From 8c876199b1a7ce3d136809c7149dde91a51be3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berke=20Kocao=C4=9Flu?= Date: Sat, 2 Jul 2022 21:02:02 +0600 Subject: [PATCH 01/18] add clang-format Co-authored-by: NRK --- .clang-format | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..18bcf9c --- /dev/null +++ b/.clang-format @@ -0,0 +1,79 @@ +--- + +Standard: c++03 + +ColumnLimit: 0 + +AccessModifierOffset: -8 +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +IndentCaseLabels: false +IndentGotoLabels: false +IndentPPDirectives: None +IndentWidth: 8 +IndentWrappedFunctionNames: false +NamespaceIndentation: None +TabWidth: 8 +UseTab: AlignWithSpaces + +AlignAfterOpenBracket: true +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: false +AlignOperands: true +AlignTrailingComments: false +DerivePointerAlignment: true +PointerAlignment: true + +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false + +BinPackArguments: true +BinPackParameters: true + +BreakBeforeBraces: Custom +BraceWrapping: + AfterControlStatement: MultiLine + AfterEnum: false + AfterExternBlock: false + AfterFunction: true + AfterStruct: false + AfterUnion: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + +BreakBeforeBinaryOperators: None +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: BeforeComma +BreakConstructorInitializersBeforeComma: false +BreakStringLiterals: true + +Cpp11BracedListStyle: false +MaxEmptyLinesToKeep: 1 + +ReflowComments: false + +SortIncludes: true + +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false + +... From 2434e83807360bfe43e3c404be12438f00a894ab Mon Sep 17 00:00:00 2001 From: NRK Date: Sat, 2 Jul 2022 21:06:24 +0600 Subject: [PATCH 02/18] make some changes prepping for clang-format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Berke Kocaoğlu --- commands.c | 8 ++++---- image.c | 9 +++++---- main.c | 25 +++++++++++++------------ window.c | 4 ++-- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/commands.c b/commands.c index a4ae38d..db1cb09 100644 --- a/commands.c +++ b/commands.c @@ -326,10 +326,10 @@ bool ci_drag(arg_t drag_mode) while (true) { if (drag_mode == DRAG_ABSOLUTE) { - px = MIN(MAX(0.0, x - win.w*0.1), win.w*0.8) / (win.w*0.8) - * (win.w - img.w * img.zoom); - py = MIN(MAX(0.0, y - win.h*0.1), win.h*0.8) / (win.h*0.8) - * (win.h - img.h * img.zoom); + px = MIN(MAX(0.0, x - win.w*0.1), win.w*0.8) / + (win.w*0.8) * (win.w - img.w * img.zoom); + py = MIN(MAX(0.0, y - win.h*0.1), win.h*0.8) / + (win.h*0.8) * (win.h - img.h * img.zoom); } else { px = img.x + x - ox; py = img.y + y - oy; diff --git a/image.c b/image.c index cded0fe..2f5d697 100644 --- a/image.c +++ b/image.c @@ -282,8 +282,9 @@ static bool img_load_gif(img_t *img, const fileinfo_t *file) if (i < y || i >= y + h || j < x || j >= x + w || rows[i-y][j-x] == transp) { - if (prev_frame != NULL && (prev_disposal != 2 || - i < py || i >= py + ph || j < px || j >= px + pw)) + if (prev_frame != NULL && + (prev_disposal != 2 || i < py || i >= py + ph || + j < px || j >= px + pw)) { *ptr = prev_frame[i * sw + j]; } else { @@ -412,8 +413,8 @@ static bool img_load_webp(img_t *img, const fileinfo_t *file) /* Load and decode frames (also works on images with only 1 frame) */ m->length = m->cnt = m->sel = 0; while (WebPAnimDecoderGetNext(dec, &buf, &ts)) { - im = imlib_create_image_using_copied_data( - info.canvas_width, info.canvas_height, (uint32_t *)buf); + im = imlib_create_image_using_copied_data(info.canvas_width, info.canvas_height, + (uint32_t *)buf); imlib_context_set_image(im); imlib_image_set_format("webp"); /* Get an iterator of this frame - used for frame info (duration, etc.) */ diff --git a/main.c b/main.c index 9541b6d..322fd74 100644 --- a/main.c +++ b/main.c @@ -40,15 +40,15 @@ #include #include -#define MODMASK(mask) ((mask) & USED_MODMASK) +#define MODMASK(mask) (USED_MODMASK & (mask)) #define BAR_SEP " " #define TV_DIFF(t1,t2) (((t1)->tv_sec - (t2)->tv_sec ) * 1000 + \ ((t1)->tv_usec - (t2)->tv_usec) / 1000) -#define TV_ADD_MSEC(tv,t) { \ +#define TV_ADD_MSEC(tv,t) do { \ (tv)->tv_sec += (t) / 1000; \ (tv)->tv_usec += (t) % 1000 * 1000; \ -} +} while (0) typedef struct { int err; @@ -200,8 +200,8 @@ void remove_file(int n, bool manual) if (n + 1 < filecnt) { if (tns.thumbs != NULL) { - memmove(tns.thumbs + n, tns.thumbs + n + 1, (filecnt - n - 1) * - sizeof(*tns.thumbs)); + memmove(tns.thumbs + n, tns.thumbs + n + 1, + (filecnt - n - 1) * sizeof(*tns.thumbs)); memset(tns.thumbs + filecnt - 1, 0, sizeof(*tns.thumbs)); } memmove(files + n, files + n + 1, (filecnt - n - 1) * sizeof(*files)); @@ -377,7 +377,7 @@ void load_image(int new) if (new >= filecnt) new = filecnt - 1; else if (new > 0 && prev) - new--; + new -= 1; } files[new].flags &= ~FF_WARN; fileidx = current = new; @@ -562,8 +562,9 @@ void handle_key_handler(bool init) return; if (init) { close_info(); - snprintf(win.bar.l.buf, win.bar.l.size, "Getting key handler input " - "(%s to abort)...", XKeysymToString(KEYHANDLER_ABORT)); + snprintf(win.bar.l.buf, win.bar.l.size, + "Getting key handler input (%s to abort)...", + XKeysymToString(KEYHANDLER_ABORT)); } else { /* abort */ open_info(); update_info(); @@ -739,8 +740,8 @@ static void run(void) init_thumb = mode == MODE_THUMB && tns.initnext < filecnt; load_thumb = mode == MODE_THUMB && tns.loadnext < tns.end; - if ((init_thumb || load_thumb || to_set || info.fd != -1 || - arl.fd != -1) && XPending(win.env.dpy) == 0) + if ((init_thumb || load_thumb || to_set || info.fd != -1 || arl.fd != -1) && + XPending(win.env.dpy) == 0) { if (load_thumb) { set_timeout(redraw, TO_REDRAW_THUMBS, false); @@ -793,8 +794,8 @@ static void run(void) discard = ev.type == nextev.type; break; case KeyPress: - discard = (nextev.type == KeyPress || nextev.type == KeyRelease) - && ev.xkey.keycode == nextev.xkey.keycode; + discard = (nextev.type == KeyPress || nextev.type == KeyRelease) && + ev.xkey.keycode == nextev.xkey.keycode; break; } } diff --git a/window.c b/window.c index 85ad542..765f67d 100644 --- a/window.c +++ b/window.c @@ -226,8 +226,8 @@ void win_open(win_t *win) if (gmask & YValue) { if (gmask & YNegative) { win->y += e->scrh - win->h; - sizehints.win_gravity = sizehints.win_gravity == NorthEastGravity - ? SouthEastGravity : SouthWestGravity; + sizehints.win_gravity = sizehints.win_gravity == NorthEastGravity ? + SouthEastGravity : SouthWestGravity; } sizehints.flags |= USPosition; } else { From f2f4903de4bd3ce06c03dd66f0c9a7dda97a3550 Mon Sep 17 00:00:00 2001 From: NRK Date: Fri, 10 Feb 2023 11:35:53 +0600 Subject: [PATCH 03/18] apply clang-format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit minus the bogus changes Co-authored-by: Berke Kocaoğlu --- autoreload.c | 20 +++++++++++++------- commands.c | 14 ++++++++------ image.c | 36 ++++++++++++++++++------------------ main.c | 47 ++++++++++++++++++++++++++--------------------- options.c | 5 +++-- thumbs.c | 26 +++++++++++++++----------- util.c | 21 +++++++++++---------- window.c | 28 ++++++++++++++++------------ 8 files changed, 110 insertions(+), 87 deletions(-) diff --git a/autoreload.c b/autoreload.c index 1c2fbf7..8b3f6da 100644 --- a/autoreload.c +++ b/autoreload.c @@ -28,7 +28,10 @@ #include #include -static struct { char *buf; size_t len; } scratch; +static struct { + char *buf; + size_t len; +} scratch; void arl_init(arl_t *arl) { @@ -94,7 +97,10 @@ bool arl_handle(arl_t *arl) char *ptr; const struct inotify_event *e; /* inotify_event aligned buffer */ - static union { char d[4096]; struct inotify_event e; } buf; + static union { + char d[4096]; + struct inotify_event e; + } buf; while (true) { ssize_t len = read(arl->fd, buf.d, sizeof(buf.d)); @@ -105,7 +111,7 @@ bool arl_handle(arl_t *arl) break; } for (ptr = buf.d; ptr < buf.d + len; ptr += sizeof(*e) + e->len) { - e = (const struct inotify_event*) ptr; + e = (const struct inotify_event *)ptr; if (e->wd == arl->wd_file && (e->mask & IN_CLOSE_WRITE)) { reload = true; } else if (e->wd == arl->wd_file && (e->mask & IN_DELETE_SELF)) { @@ -128,18 +134,18 @@ void arl_init(arl_t *arl) void arl_cleanup(arl_t *arl) { - (void) arl; + (void)arl; } void arl_add(arl_t *arl, const char *filepath) { - (void) arl; - (void) filepath; + (void)arl; + (void)filepath; } bool arl_handle(arl_t *arl) { - (void) arl; + (void)arl; return false; } diff --git a/commands.c b/commands.c index db1cb09..7c44ace 100644 --- a/commands.c +++ b/commands.c @@ -326,10 +326,10 @@ bool ci_drag(arg_t drag_mode) while (true) { if (drag_mode == DRAG_ABSOLUTE) { - px = MIN(MAX(0.0, x - win.w*0.1), win.w*0.8) / - (win.w*0.8) * (win.w - img.w * img.zoom); - py = MIN(MAX(0.0, y - win.h*0.1), win.h*0.8) / - (win.h*0.8) * (win.h - img.h * img.zoom); + px = MIN(MAX(0.0, x - win.w * 0.1), win.w * 0.8) / + (win.w * 0.8) * (win.w - img.w * img.zoom); + py = MIN(MAX(0.0, y - win.h * 0.1), win.h * 0.8) / + (win.h * 0.8) * (win.h - img.h * img.zoom); } else { px = img.x + x - ox; py = img.y + y - oy; @@ -343,7 +343,8 @@ bool ci_drag(arg_t drag_mode) ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e); if (e.type == ButtonPress || e.type == ButtonRelease) break; - while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e)); + while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e)) + ; ox = x; oy = y; x = e.xmotion.x; @@ -443,7 +444,8 @@ bool ct_drag_mark_image(arg_t _) ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e); if (e.type == ButtonPress || e.type == ButtonRelease) break; - while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e)); + while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e)) + ; sel = tns_translate(&tns, e.xbutton.x, e.xbutton.y); } } diff --git a/image.c b/image.c index 2f5d697..42979c7 100644 --- a/image.c +++ b/image.c @@ -55,7 +55,7 @@ enum { DEF_WEBP_DELAY = 75 }; #endif #define ZOOM_MIN (zoom_levels[0] / 100) -#define ZOOM_MAX (zoom_levels[ARRLEN(zoom_levels)-1] / 100) +#define ZOOM_MAX (zoom_levels[ARRLEN(zoom_levels) - 1] / 100) static int calc_cache_size(void) { @@ -69,7 +69,7 @@ static int calc_cache_size(void) #endif if (pages < 0 || page_size < 0) return CACHE_SIZE_FALLBACK; - cache = (pages/100) * CACHE_SIZE_MEM_PERCENTAGE; + cache = (pages / 100) * CACHE_SIZE_MEM_PERCENTAGE; cache *= page_size; return MIN(cache, CACHE_SIZE_LIMIT); @@ -234,12 +234,12 @@ static bool img_load_gif(img_t *img, const fileinfo_t *file) while (ext) { if (ext_code == GRAPHICS_EXT_FUNC_CODE) { if (ext[1] & 1) - transp = (int) ext[4]; + transp = (int)ext[4]; else transp = -1; - delay = 10 * ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]); - disposal = (unsigned int) ext[1] >> 2 & 0x7; + delay = 10 * ((unsigned int)ext[3] << 8 | (unsigned int)ext[2]); + disposal = (unsigned int)ext[1] >> 2 & 0x7; } ext = NULL; DGifGetExtensionNext(gif, &ext); @@ -280,7 +280,7 @@ static bool img_load_gif(img_t *img, const fileinfo_t *file) for (i = 0; i < sh; i++) { for (j = 0; j < sw; j++) { if (i < y || i >= y + h || j < x || j >= x + w || - rows[i-y][j-x] == transp) + rows[i - y][j - x] == transp) { if (prev_frame != NULL && (prev_disposal != 2 || i < py || i >= py + ph || @@ -292,9 +292,9 @@ static bool img_load_gif(img_t *img, const fileinfo_t *file) } } else { assert(cmap != NULL); - r = cmap->Colors[rows[i-y][j-x]].Red; - g = cmap->Colors[rows[i-y][j-x]].Green; - b = cmap->Colors[rows[i-y][j-x]].Blue; + r = cmap->Colors[rows[i - y][j - x]].Red; + g = cmap->Colors[rows[i - y][j - x]].Green; + b = cmap->Colors[rows[i - y][j - x]].Blue; *ptr = 0xffu << 24 | r << 16 | g << 8 | b; } ptr++; @@ -418,7 +418,7 @@ static bool img_load_webp(img_t *img, const fileinfo_t *file) imlib_context_set_image(im); imlib_image_set_format("webp"); /* Get an iterator of this frame - used for frame info (duration, etc.) */ - WebPDemuxGetFrame(demux, m->cnt+1, &iter); + WebPDemuxGetFrame(demux, m->cnt + 1, &iter); imlib_image_set_has_alpha((flags & ALPHA_FLAG) == ALPHA_FLAG); /* Store info for this frame */ m->frames[m->cnt].im = im; @@ -674,8 +674,8 @@ static bool img_fit(img_t *img) if (img->scalemode == SCALE_ZOOM) return false; - zw = (float) img->win->w / (float) img->w; - zh = (float) img->win->h / (float) img->h; + zw = (float)img->win->w / (float)img->w; + zh = (float)img->win->h / (float)img->h; switch (img->scalemode) { case SCALE_FILL: @@ -693,7 +693,7 @@ static bool img_fit(img_t *img) } z = MIN(z, img->scalemode == SCALE_DOWN ? 1.0 : ZOOM_MAX); - if (ABS(img->zoom - z) > 1.0/MAX(img->w, img->h)) { + if (ABS(img->zoom - z) > 1.0 / MAX(img->w, img->h)) { img->zoom = z; img->dirty = title_dirty = true; return true; @@ -839,14 +839,14 @@ bool img_zoom_to(img_t *img, float z) bool img_zoom(img_t *img, int d) { - int i = d > 0 ? 0 : (int)ARRLEN(zoom_levels)-1; + int i = d > 0 ? 0 : (int)ARRLEN(zoom_levels) - 1; while (i >= 0 && i < (int)ARRLEN(zoom_levels) && - (d > 0 ? zoom_levels[i]/100 <= img->zoom : zoom_levels[i]/100 >= img->zoom)) + (d > 0 ? zoom_levels[i] / 100 <= img->zoom : zoom_levels[i] / 100 >= img->zoom)) { i += d; } - i = MIN(MAX(i, 0), (int)ARRLEN(zoom_levels)-1); - return img_zoom_to(img, zoom_levels[i]/100); + i = MIN(MAX(i, 0), (int)ARRLEN(zoom_levels) - 1); + return img_zoom_to(img, zoom_levels[i] / 100); } bool img_pos(img_t *img, float x, float y) @@ -883,7 +883,7 @@ bool img_pan(img_t *img, direction_t dir, int d) float x, y; if (d > 0) { - x = y = MAX(1, (float) d * img->zoom); + x = y = MAX(1, (float)d * img->zoom); } else { x = img->win->w / (d < 0 ? 1 : PAN_FRACTION); y = img->win->h / (d < 0 ? 1 : PAN_FRACTION); diff --git a/main.c b/main.c index 322fd74..3868e8e 100644 --- a/main.c +++ b/main.c @@ -45,10 +45,11 @@ #define TV_DIFF(t1,t2) (((t1)->tv_sec - (t2)->tv_sec ) * 1000 + \ ((t1)->tv_usec - (t2)->tv_usec) / 1000) -#define TV_ADD_MSEC(tv,t) do { \ - (tv)->tv_sec += (t) / 1000; \ - (tv)->tv_usec += (t) % 1000 * 1000; \ -} while (0) +#define TV_ADD_MSEC(tv, t) \ + do { \ + (tv)->tv_sec += (t) / 1000; \ + (tv)->tv_usec += (t) % 1000 * 1000; \ + } while (0) typedef struct { int err; @@ -112,8 +113,8 @@ static void cleanup(void) static bool xgetline(char **lineptr, size_t *n) { ssize_t len = getdelim(lineptr, n, options->using_null ? '\0' : '\n', stdin); - if (!options->using_null && len > 0 && (*lineptr)[len-1] == '\n') - (*lineptr)[len-1] = '\0'; + if (!options->using_null && len > 0 && (*lineptr)[len - 1] == '\n') + (*lineptr)[len - 1] = '\0'; return len > 0; } @@ -140,7 +141,7 @@ static void check_add_file(const char *filename, bool given) if (fileidx == filecnt) { filecnt *= 2; files = erealloc(files, filecnt * sizeof(*files)); - memset(&files[filecnt/2], 0, filecnt/2 * sizeof(*files)); + memset(&files[filecnt / 2], 0, filecnt / 2 * sizeof(*files)); } files[fileidx].name = estrdup(filename); @@ -193,8 +194,8 @@ void remove_file(int n, bool manual) markcnt--; if (files[n].path != files[n].name) - free((void*) files[n].path); - free((void*) files[n].name); + free((void *)files[n].path); + free((void *)files[n].name); if (tns.thumbs != NULL) tns_unload(&tns, n); @@ -287,7 +288,7 @@ static void read_title(void) ssize_t n; char buf[512]; - if ((n = read(wintitle.fd, buf, sizeof(buf)-1)) > 0) { + if ((n = read(wintitle.fd, buf, sizeof(buf) - 1)) > 0) { buf[n] = '\0'; win_set_title(&win, buf, n); } @@ -308,7 +309,7 @@ static void open_title(void) snprintf(h, ARRLEN(h), "%d", img.h); snprintf(z, ARRLEN(z), "%d", (int)(img.zoom * 100)); } - snprintf(fidx, ARRLEN(fidx), "%d", fileidx+1); + snprintf(fidx, ARRLEN(fidx), "%d", fileidx + 1); snprintf(fcnt, ARRLEN(fcnt), "%d", filecnt); construct_argv(argv, ARRLEN(argv), wintitle.f.cmd, files[fileidx].path, fidx, fcnt, w, h, z, NULL); @@ -426,7 +427,8 @@ static void update_info(void) /* update bar contents */ if (win.bar.h == 0 || extprefix) return; - for (fw = 0, i = filecnt; i > 0; fw++, i /= 10); + for (fw = 0, i = filecnt; i > 0; fw++, i /= 10) + ; mark = files[fileidx].flags & FF_MARK ? "* " : ""; l->p = l->buf; r->p = r->buf; @@ -452,9 +454,10 @@ static void update_info(void) bar_put(r, "B%+d" BAR_SEP, img.brightness); if (img.contrast) bar_put(r, "C%+d" BAR_SEP, img.contrast); - bar_put(r, "%3d%%" BAR_SEP, (int) (img.zoom * 100.0)); + bar_put(r, "%3d%%" BAR_SEP, (int)(img.zoom * 100.0)); if (img.multi.cnt > 0) { - for (fn = 0, i = img.multi.cnt; i > 0; fn++, i /= 10); + for (fn = 0, i = img.multi.cnt; i > 0; fn++, i /= 10) + ; bar_put(r, "%0*d/%d" BAR_SEP, fn, img.multi.sel + 1, img.multi.cnt); } bar_put(r, "%0*d/%d", fw, fileidx + 1, filecnt); @@ -623,7 +626,8 @@ static bool run_key_handler(const char *key, unsigned int mask) } } fclose(pfs); - while (waitpid(pid, NULL, 0) == -1 && errno == EINTR); + while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) + ; for (f = i = 0; f < fcnt; i++) { if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) { @@ -640,7 +644,8 @@ static bool run_key_handler(const char *key, unsigned int mask) } } /* drop user input events that occurred while running the key handler */ - while (XCheckIfEvent(win.env.dpy, &dump, is_input_ev, NULL)); + while (XCheckIfEvent(win.env.dpy, &dump, is_input_ev, NULL)) + ; if (mode == MODE_IMAGE && changed) { img_close(&img, true); @@ -699,7 +704,7 @@ static void on_keypress(XKeyEvent *kev) handle_key_handler(false); } else if (key >= '0' && key <= '9') { /* number prefix for commands */ - prefix = prefix * 10 + (int) (key - '0'); + prefix = prefix * 10 + (int)(key - '0'); return; } else { dirty = process_bindings(keys, ARRLEN(keys), ksym, kev->state, sh); @@ -730,7 +735,7 @@ static void run(void) enum { FD_X, FD_INFO, FD_TITLE, FD_ARL, FD_CNT }; struct pollfd pfd[FD_CNT]; int timeout = 0; - const struct timespec ten_ms = {0, 10000000}; + const struct timespec ten_ms = { 0, 10000000 }; bool discard, init_thumb, load_thumb, to_set; XEvent ev, nextev; @@ -795,7 +800,7 @@ static void run(void) break; case KeyPress: discard = (nextev.type == KeyPress || nextev.type == KeyRelease) && - ev.xkey.keycode == nextev.xkey.keycode; + ev.xkey.keycode == nextev.xkey.keycode; break; } } @@ -806,7 +811,7 @@ static void run(void) on_buttonpress(&ev.xbutton); break; case ClientMessage: - if ((Atom) ev.xclient.data.l[0] == atoms[ATOM_WM_DELETE_WINDOW]) + if ((Atom)ev.xclient.data.l[0] == atoms[ATOM_WM_DELETE_WINDOW]) cg_quit(EXIT_SUCCESS); break; case DestroyNotify: @@ -859,7 +864,7 @@ int main(int argc, char *argv[]) size_t n; const char *homedir, *dsuffix = ""; - setup_signal(SIGCHLD, SIG_DFL, SA_RESTART|SA_NOCLDSTOP|SA_NOCLDWAIT); + setup_signal(SIGCHLD, SIG_DFL, SA_RESTART | SA_NOCLDSTOP | SA_NOCLDWAIT); setup_signal(SIGPIPE, SIG_IGN, 0); setlocale(LC_COLLATE, ""); diff --git a/options.c b/options.c index 6231d03..ef874ac 100644 --- a/options.c +++ b/options.c @@ -43,7 +43,8 @@ void print_usage(void) { printf("usage: %s [-abcfhiopqrtvZ0] [-A FRAMERATE] [-e WID] [-G GAMMA] " "[-g GEOMETRY] [-N NAME] [-n NUM] [-S DELAY] [-s MODE] " - "[-z ZOOM] FILES...\n", progname); + "[-z ZOOM] FILES...\n", + progname); } static void print_version(void) @@ -227,7 +228,7 @@ void parse_options(int argc, char **argv) if (*end != '\0' || n <= 0) error(EXIT_FAILURE, 0, "Invalid zoom level: %s", op.optarg); _options.scalemode = SCALE_ZOOM; - _options.zoom = (float) n / 100.0f; + _options.zoom = (float)n / 100.0f; break; case '0': _options.using_null = true; diff --git a/thumbs.c b/thumbs.c index b5da098..c1778b5 100644 --- a/thumbs.c +++ b/thumbs.c @@ -36,7 +36,7 @@ static char *cache_dir; -static char* tns_cache_filepath(const char *filepath) +static char *tns_cache_filepath(const char *filepath) { size_t len; char *cfile = NULL; @@ -201,8 +201,8 @@ static Imlib_Image tns_scale_down(Imlib_Image im, int dim) imlib_context_set_image(im); w = imlib_image_get_width(); h = imlib_image_get_height(); - zw = (float) dim / (float) w; - zh = (float) dim / (float) h; + zw = (float)dim / (float)w; + zh = (float)dim / (float)h; z = MIN(zw, zh); z = MIN(z, 1.0); @@ -219,7 +219,7 @@ static Imlib_Image tns_scale_down(Imlib_Image im, int dim) bool tns_load(tns_t *tns, int n, bool force, bool cache_only) { - int maxwh = thumb_sizes[ARRLEN(thumb_sizes)-1]; + int maxwh = thumb_sizes[ARRLEN(thumb_sizes) - 1]; bool cache_hit = false; char *cfile; thumb_t *t; @@ -290,8 +290,8 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only) h = imlib_image_get_height(); if (pw > w && ph > h && (pw - ph >= 0) == (w - h >= 0)) { - zw = (float) pw / (float) w; - zh = (float) ph / (float) h; + zw = (float)pw / (float)w; + zh = (float)ph / (float)h; if (zw < zh) { pw /= zh; x = (w - pw) / 2; @@ -343,10 +343,14 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only) } file->flags |= FF_TN_INIT; - if (n == tns->initnext) - while (++tns->initnext < *tns->cnt && ((++file)->flags & FF_TN_INIT)); - if (n == tns->loadnext && !cache_only) - while (++tns->loadnext < tns->end && (++t)->im != NULL); + if (n == tns->initnext) { + while (++tns->initnext < *tns->cnt && ((++file)->flags & FF_TN_INIT)) + ; + } + if (n == tns->loadnext && !cache_only) { + while (++tns->loadnext < tns->end && (++t)->im != NULL) + ; + } return true; } @@ -557,7 +561,7 @@ bool tns_zoom(tns_t *tns, int d) oldzl = tns->zl; tns->zl += -(d < 0) + (d > 0); tns->zl = MAX(tns->zl, 0); - tns->zl = MIN(tns->zl, (int)ARRLEN(thumb_sizes)-1); + tns->zl = MIN(tns->zl, (int)ARRLEN(thumb_sizes) - 1); tns->bw = ((thumb_sizes[tns->zl] - 1) >> 5) + 1; tns->bw = MIN(tns->bw, 4); diff --git a/util.c b/util.c index 1e6bc70..c7fb210 100644 --- a/util.c +++ b/util.c @@ -32,7 +32,7 @@ extern char **environ; const char *progname = "nsxiv"; -void* emalloc(size_t size) +void *emalloc(size_t size) { void *ptr; @@ -42,7 +42,7 @@ void* emalloc(size_t size) return ptr; } -void* ecalloc(size_t nmemb, size_t size) +void *ecalloc(size_t nmemb, size_t size) { void *ptr; @@ -52,7 +52,7 @@ void* ecalloc(size_t nmemb, size_t size) return ptr; } -void* erealloc(void *ptr, size_t size) +void *erealloc(void *ptr, size_t size) { ptr = realloc(ptr, size); if (ptr == NULL) @@ -60,13 +60,13 @@ void* erealloc(void *ptr, size_t size) return ptr; } -char* estrdup(const char *s) +char *estrdup(const char *s) { size_t n = strlen(s) + 1; return memcpy(emalloc(n), s, n); } -void error(int eval, int err, const char* fmt, ...) +void error(int eval, int err, const char *fmt, ...) { va_list ap; @@ -102,7 +102,7 @@ int r_opendir(r_dir_t *rdir, const char *dirname, bool recursive) rdir->stack = emalloc(rdir->stcap * sizeof(*rdir->stack)); rdir->stlen = 0; - rdir->name = (char*) dirname; + rdir->name = (char *)dirname; rdir->d = 0; rdir->recursive = recursive; @@ -133,7 +133,7 @@ int r_closedir(r_dir_t *rdir) return ret; } -char* r_readdir(r_dir_t *rdir, bool skip_dotfiles) +char *r_readdir(r_dir_t *rdir, bool skip_dotfiles) { size_t len; char *filename; @@ -154,7 +154,7 @@ char* r_readdir(r_dir_t *rdir, bool skip_dotfiles) len = strlen(rdir->name) + strlen(dentry->d_name) + 2; filename = emalloc(len); snprintf(filename, len, "%s%s%s", rdir->name, - rdir->name[strlen(rdir->name)-1] == '/' ? "" : "/", + rdir->name[strlen(rdir->name) - 1] == '/' ? "" : "/", dentry->d_name); if (stat(filename, &fstats) < 0) { @@ -203,7 +203,8 @@ int r_mkdir(char *path) s++; continue; } - for (; *s != '\0' && *s != '/'; s++); + for (; *s != '\0' && *s != '/'; s++) + ; c = *s; *s = '\0'; if (mkdir(path, 0755) == -1) { @@ -226,7 +227,7 @@ void construct_argv(char **argv, unsigned int len, ...) for (i = 0; i < len; ++i) argv[i] = va_arg(args, char *); va_end(args); - assert(argv[len-1] == NULL && "argv should be NULL terminated"); + assert(argv[len - 1] == NULL && "argv should be NULL terminated"); } static int mkspawn_pipe(posix_spawn_file_actions_t *fa, const char *cmd, int *pfd, int dupidx) diff --git a/window.c b/window.c index 765f67d..3857871 100644 --- a/window.c +++ b/window.c @@ -34,7 +34,7 @@ #if HAVE_LIBFONTS #include "utf8.h" -#define UTF8_PADDING 4 /* utf8_decode requires 4 bytes of zero padding */ +#define UTF8_PADDING 4 /* utf8_decode requires 4 bytes of zero padding */ #define TEXTWIDTH(win, text, len) \ win_draw_text(win, NULL, NULL, 0, 0, text, len, 0) #endif @@ -56,8 +56,12 @@ static struct { int name; Cursor icon; } cursors[CURSOR_COUNT] = { - { XC_left_ptr }, { XC_dotbox }, { XC_fleur }, { XC_watch }, - { XC_sb_left_arrow }, { XC_sb_right_arrow } + { XC_left_ptr }, + { XC_dotbox }, + { XC_fleur }, + { XC_watch }, + { XC_sb_left_arrow }, + { XC_sb_right_arrow } }; #if HAVE_LIBFONTS @@ -90,7 +94,7 @@ static void win_alloc_color(const win_env_t *e, const char *name, XColor *col) error(EXIT_FAILURE, 0, "Error allocating color '%s'", name); } -static const char* win_res(XrmDatabase db, const char *name, const char *def) +static const char *win_res(XrmDatabase db, const char *name, const char *def) { char *type; XrmValue ret; @@ -246,7 +250,7 @@ void win_open(win_t *win) /* set the _NET_WM_PID */ pid = getpid(); XChangeProperty(e->dpy, win->xwin, atoms[ATOM__NET_WM_PID], XA_CARDINAL, - 32, PropModeReplace, (unsigned char *) &pid, 1); + 32, PropModeReplace, (unsigned char *)&pid, 1); if (gethostname(hostname, ARRLEN(hostname)) == 0) { XTextProperty tp; tp.value = (unsigned char *)hostname; @@ -272,7 +276,7 @@ void win_open(win_t *win) gc = XCreateGC(e->dpy, win->xwin, 0, None); - n = icons[ARRLEN(icons)-1].size; + n = icons[ARRLEN(icons) - 1].size; icon_data = emalloc((n * n + 2) * sizeof(*icon_data)); for (i = 0; i < (int)ARRLEN(icons); i++) { @@ -286,7 +290,7 @@ void win_open(win_t *win) } XChangeProperty(e->dpy, win->xwin, atoms[ATOM__NET_WM_ICON], XA_CARDINAL, 32, i == 0 ? PropModeReplace : PropModeAppend, - (unsigned char *) icon_data, n); + (unsigned char *)icon_data, n); } free(icon_data); @@ -311,7 +315,7 @@ void win_open(win_t *win) if (options->fullscreen) { XChangeProperty(e->dpy, win->xwin, atoms[ATOM__NET_WM_STATE], XA_ATOM, 32, PropModeReplace, - (unsigned char *) &atoms[ATOM__NET_WM_STATE_FULLSCREEN], 1); + (unsigned char *)&atoms[ATOM__NET_WM_STATE_FULLSCREEN], 1); } win->h -= win->bar.h; @@ -432,10 +436,10 @@ static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color, FC_SIZE, FcTypeDouble, fontsize, NULL); FcCharSetDestroy(fccharset); } - XftTextExtentsUtf8(win->env.dpy, f, (XftChar8*)t, next - t, &ext); + XftTextExtentsUtf8(win->env.dpy, f, (XftChar8 *)t, next - t, &ext); tw += ext.xOff; if (tw <= w) { - XftDrawStringUtf8(d, color, f, x, y, (XftChar8*)t, next - t); + XftDrawStringUtf8(d, color, f, x, y, (XftChar8 *)t, next - t); x += ext.xOff; } if (f != font) @@ -456,7 +460,7 @@ static void win_draw_bar(win_t *win) r = &win->bar.r; assert(l->buf != NULL && r->buf != NULL); y = (win->bar.top ? 0 : win->h) + font->ascent + V_TEXT_PAD; - w = win->w - 2*H_TEXT_PAD; + w = win->w - 2 * H_TEXT_PAD; d = XftDrawCreate(e->dpy, win->buf.pm, e->vis, e->cmap); XSetForeground(e->dpy, gc, win->bar_bg.pixel); @@ -482,7 +486,7 @@ static void win_draw_bar(win_t *win) #else static void win_draw_bar(win_t *win) { - (void) win; + (void)win; } #endif /* HAVE_LIBFONTS */ From 157646f54cd010c8c884998319954006260f960e Mon Sep 17 00:00:00 2001 From: NRK Date: Fri, 10 Feb 2023 11:51:53 +0600 Subject: [PATCH 04/18] etc changes related to code-style docs * Add a "Code Style" section in CONTRIBUTING * Move .clang-format to etc/ * Add a short comment on clang-format and editorconfig file --- .editorconfig | 2 ++ .clang-format => etc/.clang-format | 3 +++ etc/CONTRIBUTING.md | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) rename .clang-format => etc/.clang-format (89%) diff --git a/.editorconfig b/.editorconfig index 72b2e5e..cbc0f4b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,6 @@ # EditorConfig +# See this if your editor doesn't have built-in editorconfig support: +# https://editorconfig.org/#download # apply to all files [*] diff --git a/.clang-format b/etc/.clang-format similarity index 89% rename from .clang-format rename to etc/.clang-format index 18bcf9c..a29be62 100644 --- a/.clang-format +++ b/etc/.clang-format @@ -1,3 +1,6 @@ +# clang-format doesn't dictate the project's code style and can mess up a +# couple edge cases. However it comes quite close and can be used for fixing +# most style issues automatically on new changes via `git-clang-format`. --- Standard: c++03 diff --git a/etc/CONTRIBUTING.md b/etc/CONTRIBUTING.md index 8d9680f..aa96068 100644 --- a/etc/CONTRIBUTING.md +++ b/etc/CONTRIBUTING.md @@ -23,7 +23,7 @@ Contribution Guideline When contributing, make sure: * Your contribution falls under nsxiv's scope and aim - * You follow the existing code style (see [.editorconfig](../.editorconfig)) + * You follow the existing code style (see the "Code Style" section below) * You open the pull request from a new branch, not from master * To avoid using force pushes, especially for bigger patches. Only use them when there's merge conflicts. @@ -44,6 +44,21 @@ to work on. You can also filter the issues via label: (Intermediate/Experienced) Issues where we require some help. +Code Style +---------- + +`nsxiv` mostly follows the [suckless code-style][sl], with a few exceptions. +If your editor supports [.editorconfig](../.editorconfig) then you'll already be +off to a good start without needing much manual intervention. Additionally we +provide a [clang-format](./.clang-format) configuration for reference, which you +may use via [`git-clang-format`][cf] to format the changes you've made (please +do not run it globally on the entire code-base since clang-format gets a decent +amount of edge cases wrong). + +[sl]: https://suckless.org/coding_style/ +[cf]: https://clang.llvm.org/docs/ClangFormat.html#git-integration + + Development workflow for maintainers ------------------------------------ From 502b30301c1c178748c221076f3f06f817956880 Mon Sep 17 00:00:00 2001 From: NRK Date: Fri, 17 Mar 2023 07:58:02 +0600 Subject: [PATCH 05/18] document handling of empty X resources values since 5cab2fb we reject empty X resources value to support use-cases like this: https://codeberg.org/nsxiv/nsxiv/issues/339 this issue was also bought up by GRFreire in: https://codeberg.org/nsxiv/nsxiv-record/pulls/115#issuecomment-474831 this suggests that this is a use-case that a decent amount of users might be interested in. so document the behavior so it's more easily visible. --- etc/nsxiv.1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/nsxiv.1 b/etc/nsxiv.1 index d601e5c..a75a0a0 100644 --- a/etc/nsxiv.1 +++ b/etc/nsxiv.1 @@ -457,6 +457,9 @@ Color of the bar foreground. Defaults to window.foreground Color of the mark foreground. Defaults to window.foreground .TP Please see xrdb(1) on how to change them. +.LP +An X resources entry with an empty value means the default +(defined in config.h) will be used. .SH WINDOW TITLE The window title can be replaced with the output of a user-provided script, which is called by nsxiv whenever any of the relevant information changes. From 54bfc5db042960a196e8aa291971160d36bd80f2 Mon Sep 17 00:00:00 2001 From: NRK Date: Fri, 17 Mar 2023 08:13:31 +0600 Subject: [PATCH 06/18] fix a typpo in CHANGELOG.md --- etc/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/CHANGELOG.md b/etc/CHANGELOG.md index aefb36f..5ea1259 100644 --- a/etc/CHANGELOG.md +++ b/etc/CHANGELOG.md @@ -116,7 +116,7 @@ references *above* can be found on the new main nsxiv repository on CodeBerg. * Changes: - * Window title is now customizeable via `win-title`, cli flag `-T` and related + * Window title is now customizable via `win-title`, cli flag `-T` and related config.h options are removed. See `WINDOW TITLE` section of the manpage for more info. [#213] * Imlib2 cache size is now set based on total memory percentage, by default From 4df97db1cd566fab1ed927986e40cc4542e937c5 Mon Sep 17 00:00:00 2001 From: NRK Date: Mon, 10 Apr 2023 17:13:44 +0000 Subject: [PATCH 07/18] editorconfig: only apply to .c and .h files (#433) otherwise, it ends up applying to the manpage and git commit messages too. Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/433 Reviewed-by: eylles Reviewed-by: explosion-mental --- .editorconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index cbc0f4b..bec9606 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,8 +2,8 @@ # See this if your editor doesn't have built-in editorconfig support: # https://editorconfig.org/#download -# apply to all files -[*] +# apply to all .c and .h files +[*.{c,h}] # top-most EditorConfig file root = true From 733916ad70b5b2d92e7adfecdf53a74dd4617b74 Mon Sep 17 00:00:00 2001 From: eylles Date: Fri, 14 Apr 2023 19:45:39 +0000 Subject: [PATCH 08/18] add a pick quit keybind (#432) The last time[0] this was discussed, no-one was against it but no-one was confident in it either and so it was added to nsxiv-extra as a patch. But now that enough time has passed, it seems like there's a pretty high demand for something like this because there's plenty of use-cases that use nsxiv as a "picker" where it's meant to quickly pick a single file. And so add this as a convenient default key-bind. [0]: https://codeberg.org/nsxiv/nsxiv-record/pulls/42 Co-authored-by: eylles Co-authored-by: NRK Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/432 Reviewed-by: NRK Co-authored-by: eylles Co-committed-by: eylles --- commands.c | 7 +++++++ commands.h | 2 ++ config.def.h | 1 + etc/nsxiv.1 | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/commands.c b/commands.c index 7c44ace..97cadf2 100644 --- a/commands.c +++ b/commands.c @@ -59,6 +59,13 @@ bool cg_quit(arg_t status) return None; /* silence tcc warning */ } +bool cg_pick_quit(arg_t status) +{ + if (options->to_stdout && markcnt == 0) + printf("%s%c", files[fileidx].name, options->using_null ? '\0' : '\n'); + return cg_quit(status); +} + bool cg_switch_mode(arg_t _) { if (mode == MODE_IMAGE) { diff --git a/commands.h b/commands.h index 76b1330..4e694f0 100644 --- a/commands.h +++ b/commands.h @@ -12,6 +12,7 @@ bool cg_n_or_last(arg_t); bool cg_navigate_marked(arg_t); bool cg_prefix_external(arg_t); bool cg_quit(arg_t); +bool cg_pick_quit(arg_t); bool cg_reload_image(arg_t); bool cg_remove_image(arg_t); bool cg_reverse_marks(arg_t); @@ -57,6 +58,7 @@ bool ct_select(arg_t); #define g_navigate_marked { cg_navigate_marked, MODE_ALL } #define g_prefix_external { cg_prefix_external, MODE_ALL } #define g_quit { cg_quit, MODE_ALL } +#define g_pick_quit { cg_pick_quit, MODE_ALL } #define g_reload_image { cg_reload_image, MODE_ALL } #define g_remove_image { cg_remove_image, MODE_ALL } #define g_reverse_marks { cg_reverse_marks, MODE_ALL } diff --git a/config.def.h b/config.def.h index a0935f6..5d4e97a 100644 --- a/config.def.h +++ b/config.def.h @@ -92,6 +92,7 @@ static const KeySym KEYHANDLER_ABORT = XK_Escape; static const keymap_t keys[] = { /* modifiers key function argument */ { 0, XK_q, g_quit, 0 }, + { 0, XK_Q, g_pick_quit, 0 }, { 0, XK_Return, g_switch_mode, None }, { 0, XK_f, g_toggle_fullscreen, None }, { 0, XK_b, g_toggle_bar, None }, diff --git a/etc/nsxiv.1 b/etc/nsxiv.1 index a75a0a0..10f131a 100644 --- a/etc/nsxiv.1 +++ b/etc/nsxiv.1 @@ -135,6 +135,10 @@ Prefix the next command with a number (denoted via .B q Quit nsxiv. .TP +.B Q +Quit nsxiv, but additionally print the current filename when \-o is active and +no files have been marked. +.TP .B Return Switch to thumbnail mode / open selected image in image mode. .TP From 657080a7e55843e351fa6ce41e4ce315eab62b67 Mon Sep 17 00:00:00 2001 From: NRK Date: Tue, 9 May 2023 00:34:28 +0000 Subject: [PATCH 09/18] config.mk: default to `-O2` and `-DNDEBUG` (#435) assertions are for debugging purposes, and so shouldn't be enabled for "release" builds. disable it by default by using `-DNDEBUG`. `-O2` on gcc/clang will result it slightly better binary. on tcc it'll be ignored. and since -O is specified by POSIX there shouldn't be any portability concern. additionally add a (commented out) recommended debug build for gcc/clang with address and undefined sanitizers turned on. Closes: https://codeberg.org/nsxiv/nsxiv/issues/424 Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/435 Reviewed-by: explosion-mental Reviewed-by: eylles --- config.mk | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config.mk b/config.mk index fdd50a8..44ec692 100644 --- a/config.mk +++ b/config.mk @@ -23,8 +23,11 @@ HAVE_LIBWEBP = $(OPT_DEP_DEFAULT) # Compiler and linker CC = c99 -# CFLAGS, any optimization flags goes here -CFLAGS = -Wall -pedantic +# CFLAGS, any additional compiler flags goes here +CFLAGS = -Wall -pedantic -O2 -DNDEBUG +# Uncomment for a debug build using gcc/clang +# CFLAGS = -Wall -pedantic -g3 -fsanitize=address,undefined +# LDFLAGS = $(CFLAGS) # icons that will be installed via `make icon` ICONS = 16x16.png 32x32.png 48x48.png 64x64.png 128x128.png From d7e149dbda9140595eab59bbda2f6c200fe8cc39 Mon Sep 17 00:00:00 2001 From: NRK Date: Sat, 13 May 2023 21:51:57 +0600 Subject: [PATCH 10/18] README: clarify dependency on giflib and libwebp this makes it clear that giflib and libwebp are unused if imlib2 version is sufficient for multi-frame decoding. ref: https://codeberg.org/nsxiv/nsxiv/issues/442#issuecomment-912175 --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd79471..bc303d4 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,14 @@ The following dependencies are optional. Disabled via `HAVE_INOTIFY=0`. * `libXft`, `freetype2`, `fontconfig`: Used for the status bar. Disabled via `HAVE_LIBFONTS=0`. - * `giflib`: Used for animated gif playback. - Disabled via `HAVE_LIBGIF=0`. * `libexif`: Used for auto-orientation and exif thumbnails. Disable via `HAVE_LIBEXIF=0`. + +The following dependencies are only used if your imlib2 version is lower than +v1.8.0. If your imlib2 version is v1.8.0 (or above) then the following +dependencies are unused and won't be built (even if you enable it explicitly). + + * `giflib`: Used for animated gif playback. Disabled via `HAVE_LIBGIF=0`. * `libwebp`: Used for animated webp playback. (***NOTE***: animated webp also requires Imlib2 v1.7.5 or above) Disabled via `HAVE_LIBWEBP=0`. From 5c6745436fcaca6e92b1a36a4add5aa15d17e164 Mon Sep 17 00:00:00 2001 From: NRK Date: Sat, 13 May 2023 23:28:27 +0600 Subject: [PATCH 11/18] [ci]: silence false positive warning clang-tidy currently flags the following: util.c:57:8: error: 'ptr' may be set to null if 'realloc' fails, which may result in a leak of the original buffer [bugprone-suspicious-realloc-usage,-warnings-as-errors] ptr = realloc(ptr, size); the analysis here is correct, but if realloc fails, we simply exit so there's no real "leak". moreover this check is not very useful for nsxiv's codebase because we do not use naked realloc(), instead we use the erealloc wrapper that exits on failure. so just disable the warning entirely instead of changing the source code to silence the false positive. --- etc/woodpecker/clang-tidy-checks | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/woodpecker/clang-tidy-checks b/etc/woodpecker/clang-tidy-checks index 0cc2693..edf0ba6 100644 --- a/etc/woodpecker/clang-tidy-checks +++ b/etc/woodpecker/clang-tidy-checks @@ -9,6 +9,7 @@ misc-*,android-cloexec-*,llvm-include-order -bugprone-implicit-widening-of-multiplication-result,-bugprone-integer-division -android-cloexec-fopen,-android-cloexec-pipe,-cert-err33-c -bugprone-assignment-in-if-condition +-bugprone-suspicious-realloc-usage # false positive warnings -clang-analyzer-valist.Uninitialized From 4b67816eae77db28db64e5e80d0d99c60e74973f Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 18 May 2023 15:05:45 +0000 Subject: [PATCH 12/18] fix: loading old frames due to multi-frame cache (#437) by default imlib2 doesn't check the file's timestamp to avoid disk activity when loading from cache. however, this ends up breaking our autoreload functionality on multi-frame images. the reason why single frame images weren't broken was because `img_load()` calls `imlib_image_set_changes_on_disk()`, which tells imlib2 to check the timestamp before loading from cache. do the same thing for the multi-frame loader as well. additionally add a comment to img_load() explaining what's going on. Closes: https://codeberg.org/nsxiv/nsxiv/issues/436 Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/437 Reviewed-by: eylles --- image.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/image.c b/image.c index 42979c7..49dc72f 100644 --- a/image.c +++ b/image.c @@ -506,6 +506,7 @@ static bool img_load_multiframe(img_t *img, const fileinfo_t *file) } imlib_context_set_image(frame); + imlib_image_set_changes_on_disk(); /* see img_load() for rationale */ imlib_image_get_frame_info(&finfo); assert(finfo.frame_count == (int)fcnt); assert(finfo.canvas_w == img->w && finfo.canvas_h == img->h); @@ -579,6 +580,9 @@ bool img_load(img_t *img, const fileinfo_t *file) if ((img->im = img_open(file)) == NULL) return false; + /* ensure that the image's timestamp is checked when loading from cache + * to avoid issues like: https://codeberg.org/nsxiv/nsxiv/issues/436 + */ imlib_image_set_changes_on_disk(); /* since v1.7.5, Imlib2 can parse exif orientation from jpeg files. From d0ec8716d7d4d0cfb0067290cac51b59b7fd4e42 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 18 May 2023 15:06:44 +0000 Subject: [PATCH 13/18] fix: calling imlib2 with color modifier being NULL (#440) the multiframe loaders sets the color modifier to NULL but doesn't restore it before returning. this results in a imlib2 developer warning if you try to change brightness/contrast on a multiframe image (which doesn't have alpha). ensure that the color modifier is restored before returning under all paths. Reported-by: Madhu Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/440 Reviewed-by: eylles --- image.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/image.c b/image.c index 49dc72f..4f9015d 100644 --- a/image.c +++ b/image.c @@ -470,11 +470,6 @@ static bool img_load_multiframe(img_t *img, const fileinfo_t *file) m->frames = erealloc(m->frames, m->cap * sizeof(*m->frames)); } - imlib_context_set_dither(0); - imlib_context_set_anti_alias(0); - imlib_context_set_color_modifier(NULL); - imlib_context_set_operation(IMLIB_OP_COPY); - if ((blank = imlib_create_image(img->w, img->h)) == NULL) { error(0, 0, "%s: couldn't create image", file->name); return false; @@ -482,6 +477,11 @@ static bool img_load_multiframe(img_t *img, const fileinfo_t *file) imlib_context_set_image(blank); img_area_clear(0, 0, img->w, img->h); + imlib_context_set_dither(0); + imlib_context_set_anti_alias(0); + imlib_context_set_color_modifier(NULL); + imlib_context_set_operation(IMLIB_OP_COPY); + /* * Imlib2 gives back a "raw frame", we need to blend it on top of the * previous frame ourselves if necessary to get the fully decoded frame. @@ -548,6 +548,7 @@ static bool img_load_multiframe(img_t *img, const fileinfo_t *file) imlib_context_set_image(blank); imlib_free_image(); img_multiframe_context_set(img); + imlib_context_set_color_modifier(img->cmod); /* restore cmod */ return m->cnt > 0; } #endif /* HAVE_IMLIB2_MULTI_FRAME */ From 824b2cb8858b19ace3e26a0f54cf9dd740be9b59 Mon Sep 17 00:00:00 2001 From: blk_750 Date: Fri, 19 May 2023 13:17:02 +0000 Subject: [PATCH 14/18] fix: memory leak in `win_draw_bar` (#444) Closes: https://codeberg.org/nsxiv/nsxiv/issues/410 Co-authored-by: blk_750 Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/444 Reviewed-by: NRK Co-authored-by: blk_750 Co-committed-by: blk_750 --- window.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/window.c b/window.c index 3857871..b170614 100644 --- a/window.c +++ b/window.c @@ -470,8 +470,10 @@ static void win_draw_bar(win_t *win) XSetBackground(e->dpy, gc, win->bar_bg.pixel); if ((len = strlen(r->buf)) > 0) { - if ((tw = TEXTWIDTH(win, r->buf, len)) > w) + if ((tw = TEXTWIDTH(win, r->buf, len)) > w) { + XftDrawDestroy(d); return; + } x = win->w - tw - H_TEXT_PAD; w -= tw; win_draw_text(win, d, &win->bar_fg, x, y, r->buf, len, tw); From e4fceab18f4b7856a2ef6fbabebe1988c1fbfaea Mon Sep 17 00:00:00 2001 From: a1337xyz Date: Tue, 23 May 2023 03:01:44 +0000 Subject: [PATCH 15/18] move load/cache messages to right side (#446) this avoids overwriting the left side bar, which might contain more important information, for e.g output of the thumb-info script. Co-authored-by: A1337Xyz Co-authored-by: NRK Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/446 Reviewed-by: eylles Reviewed-by: NRK Co-authored-by: a1337xyz Co-committed-by: a1337xyz --- main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 3868e8e..fed9528 100644 --- a/main.c +++ b/main.c @@ -434,12 +434,12 @@ static void update_info(void) r->p = r->buf; if (mode == MODE_THUMB) { if (tns.loadnext < tns.end) - bar_put(l, "Loading... %0*d", fw, tns.loadnext + 1); + bar_put(r, "Loading... %0*d | ", fw, tns.loadnext + 1); else if (tns.initnext < filecnt) - bar_put(l, "Caching... %0*d", fw, tns.initnext + 1); - else if (info.ft.err) - strncpy(l->buf, files[fileidx].name, l->size); + bar_put(r, "Caching... %0*d | ", fw, tns.initnext + 1); bar_put(r, "%s%0*d/%d", mark, fw, fileidx + 1, filecnt); + if (info.ft.err) + strncpy(l->buf, files[fileidx].name, l->size); } else { bar_put(r, "%s", mark); if (img.ss.on) { From 0e1bc3c045384bca18922accbc50fa6914a67bd0 Mon Sep 17 00:00:00 2001 From: NRK Date: Tue, 23 May 2023 11:36:41 +0000 Subject: [PATCH 16/18] set a default delay if delay is 0 (#445) gif spec [0] doesn't mention what to do when "Delay Time" is 0. apng spec [1] states: | If the the value of the numerator is 0 the decoder should render the | next frame as quickly as possible, though viewers may impose a | reasonable lower bound. webp spec [2]: | the interpretation of frame duration of 0 (and often <= 10) is | implementation defined. so it seems that it's safe to set a default delay for 0 delay frames, which is what the older gif and webp loaders were already doing. do the same for the imlib2 multi-frame loader as well. [0]: https://www.w3.org/Graphics/GIF/spec-gif89a.txt [1]: https://wiki.mozilla.org/APNG_Specification [2]: https://developers.google.com/speed/webp/docs/riff_container#animation Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/445 Reviewed-by: eylles --- image.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/image.c b/image.c index 4f9015d..426a05a 100644 --- a/image.c +++ b/image.c @@ -54,6 +54,10 @@ enum { DEF_GIF_DELAY = 75 }; enum { DEF_WEBP_DELAY = 75 }; #endif +#if HAVE_IMLIB2_MULTI_FRAME +enum { DEF_ANIM_DELAY = 75 }; +#endif + #define ZOOM_MIN (zoom_levels[0] / 100) #define ZOOM_MAX (zoom_levels[ARRLEN(zoom_levels) - 1] / 100) @@ -539,7 +543,7 @@ static bool img_load_multiframe(img_t *img, const fileinfo_t *file) imlib_context_set_blend(!!(finfo.frame_flags & IMLIB_FRAME_BLEND)); imlib_blend_image_onto_image(frame, has_alpha, 0, 0, sw, sh, sx, sy, sw, sh); m->frames[m->cnt].im = canvas; - m->frames[m->cnt].delay = finfo.frame_delay; + m->frames[m->cnt].delay = finfo.frame_delay ? finfo.frame_delay : DEF_ANIM_DELAY; m->length += m->frames[m->cnt].delay; m->cnt++; imlib_context_set_image(frame); From 40480596cad8654dca225e7fb136f4151f5df5c0 Mon Sep 17 00:00:00 2001 From: NRK Date: Fri, 26 May 2023 07:06:17 +0000 Subject: [PATCH 17/18] make assertions opt-in (#447) slight addendum to 657080a7e55843e351fa6ce41e4ce315eab62b67 instead of disabling asserts by adding -DNDEBUG to config.mk, this disables asserts by default in the source code itself. this way, if someone compiles with `make CFLAGS="-O3 -march=native"` without knowing about asserts/-DNDEBUG then he won't accidentally get a build with assertions in it. this basically makes the assertions opt-in, if someone wants it, he'll need to *explicitly* set `-DDEBUG` to get it. so that it's not possible to accidentally end up with assertions enabled. Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/447 Reviewed-by: TAAPArthur --- config.mk | 2 +- nsxiv.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config.mk b/config.mk index 44ec692..20bb2b2 100644 --- a/config.mk +++ b/config.mk @@ -26,7 +26,7 @@ CC = c99 # CFLAGS, any additional compiler flags goes here CFLAGS = -Wall -pedantic -O2 -DNDEBUG # Uncomment for a debug build using gcc/clang -# CFLAGS = -Wall -pedantic -g3 -fsanitize=address,undefined +# CFLAGS = -Wall -pedantic -DDEBUG -g3 -fsanitize=address,undefined # LDFLAGS = $(CFLAGS) # icons that will be installed via `make icon` diff --git a/nsxiv.h b/nsxiv.h index 8011f9e..7e373c2 100644 --- a/nsxiv.h +++ b/nsxiv.h @@ -20,6 +20,10 @@ #ifndef NSXIV_H #define NSXIV_H +#if !defined(DEBUG) && !defined(NDEBUG) + #define NDEBUG +#endif + #include #include From c03ec39437b473526080f496d6c8564e98bea1d7 Mon Sep 17 00:00:00 2001 From: NRK Date: Sun, 28 May 2023 06:49:07 +0000 Subject: [PATCH 18/18] update documentation (#448) the fedora copr repo is no longer being updated since the maintainer of it, mamg22, no longer uses nsxiv in his daily setup (and thus stopped contributing to nsxiv as well). he has requested the repo and his email to be removed from the project. so go ahead and honor that request. also take this as an opportunity to remove some long inactive maintainers from the CURRENT MAINTAINERS section of the manpage. Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/448 Reviewed-by: explosion-mental --- README.md | 4 ---- etc/nsxiv.1 | 5 ----- 2 files changed, 9 deletions(-) diff --git a/README.md b/README.md index bc303d4..70376d7 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,6 @@ nsxiv is available on the following distributions/repositories. If you don't see your distro listed here, either contact your distro's package maintainer or consider packaging it yourself and adding it to the respective community repo. -Repos not tracked by repology: - -* Fedora: Enable the copr repo via `dnf copr enable mamg22/nsxiv`. - Dependencies ------------ diff --git a/etc/nsxiv.1 b/etc/nsxiv.1 index 10f131a..e2fb4c8 100644 --- a/etc/nsxiv.1 +++ b/etc/nsxiv.1 @@ -569,11 +569,6 @@ TAAPArthur eylles Stein Gunnar Bakkeby explosion-mental -mamg22 -LuXu -Guilherme Freire -Sam Whitehead -Kian Kasad .EE .SH CONTRIBUTORS .EX