commit 95eeecbe5f3f4edfeb5f5e93b4bebd14744f30b2 from: Brett Fisher date: Thu Jun 18 06:05:28 2026 UTC bxnotify.c: Correct typo in headers and edit calc_layout() function. - Rename include to to match the actual getopt(3) declaration - Correct calc_layout so that when input contains no breakable space, hard-break is at the largest fitting prefix - Leave cfg_padding on the right for visual appeal - Add NULL checks on realloc() so memory exhaustion routes through die() and cleanup() rather than crashing - Restructure the loop so the workd-break and hard-break paths are explicit and symmetric. commit - 715dc48d96e849954524bc47757a69649abac0ac commit + 95eeecbe5f3f4edfeb5f5e93b4bebd14744f30b2 blob - e0ba0644373ae3e4f5aa93ddb249556b5c63a046 blob + e3561d389654adb32ec21d28b3a67a9d0893e0c4 --- bxnotify.c +++ bxnotify.c @@ -7,7 +7,7 @@ #define _POSIX_C_SOURCE 200809L #include -#include +#include #include #include #include @@ -208,22 +208,47 @@ calc_layout(void) for (int i = 0; i < tb.count; i++) { char *line = tb.lines[i]; - + while (measure_text(line) > cfg_width) { - /* Find break point */ + /* Try to find a space that produces a fitting prefix */ char *p = line + strlen(line); - while (p > line && measure_text(line) > cfg_width) { - while (p > line && *p != ' ') p--; - if (p == line) break; /* Cannot wrap, forced break */ + while (p > line && *p != ' ') p--; + char *chunk; + + if (p > line) { + /* Word break found: split at the space */ *p = '\0'; + chunk = strdup(line); + line = p + 1; + } else { + /* No space: hard-break on the largest fitting prefix. + * Reserve cfg_padding on the right for visual breathing room. */ + int lo = 1, hi = (int)strlen(line); + int effective_width = cfg_width - cfg_padding; + while (lo < hi) { + int mid = lo + (hi - lo + 1) / 2; + char saved = line[mid]; + line[mid] = '\0'; + if (measure_text(line) <= effective_width) + lo = mid; + else + hi = mid - 1; + line[mid] = saved; + } + char saved = line[lo]; + line[lo] = '\0'; + chunk = strdup(line); + line[lo] = saved; + line = line + lo; } - /* Add chunk */ + wrapped = realloc(wrapped, (++wrapped_count) * sizeof(char *)); - wrapped[wrapped_count - 1] = strdup(line); - line = p + 1; + if (!wrapped) die("bxnotify: realloc failed\n"); + wrapped[wrapped_count - 1] = chunk; } - /* Add remainder */ + /* Add remainder (always fits) */ wrapped = realloc(wrapped, (++wrapped_count) * sizeof(char *)); + if (!wrapped) die("bxnotify: realloc failed\n"); wrapped[wrapped_count - 1] = strdup(line); }