fb50a1cca3a117bb964c43196671142484b13bf9
braney
  Fri Jun 12 12:10:47 2026 -0700
lib jkOwnLib hg/lib: fix warnings exposed by -O3 build

At -O3 GCC does more inlining and interprocedural range analysis, which
surfaces several warnings that -O -g never triggered.  With -Werror these
break the build, so fix them ahead of switching the default to -O3.

- bamFile.c: move setenv() into the else of its NULL guard so it is not
reachable with a NULL argument (-Wnonnull, seen via inlining of bamFetch).
- basicBed.c, wormdna.c, bedDetail.c, customFactory.c, hdb.c, qaSeq.c:
replace strncpy() with safecpy() where the result must be terminated
(-Wstringop-truncation).
- htmshell.c: use memcpy() for the intentional exact-length, non-terminated
copy (-Wstringop-truncation).
- obscure.c: compute the comma groups in sprintLongWithCommas() with % 1000
so the compiler can see each %03lld argument is bounded (-Wformat-overflow).
- crudeali.c: do the endian type-pun through a union so strict-aliasing
analysis no longer reports the value as uninitialized (-Wuninitialized).
- jksql.c: wrap a possibly-NULL database name in naForNull() before passing
it to %s (-Wformat-overflow).

refs #37761

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

diff --git src/lib/obscure.c src/lib/obscure.c
index 6c1a7f374c8..3607df8d32f 100644
--- src/lib/obscure.c
+++ src/lib/obscure.c
@@ -625,67 +625,45 @@
     }
 slReverse(&list);
 return list;
 }
 
 struct slName *commaSepToSlNames(char *commaSep)
 /* Split string and convert comma-separated list of items to slName list.  */
 {
 return charSepToSlNames(commaSep, ',');
 }
 
 
 void sprintLongWithCommas(char *s, long long l)
 /* Print out a long number with commas a thousands, millions, etc. */
 {
-long long trillions, billions, millions, thousands;
+// Compute each comma-group as a value in [0,999] via modulo so the compiler can
+// see the %03lld arguments are bounded (keeps -Wformat-overflow happy at -O3).
+long long ones = l % 1000;
+long long thousands = (l/1000) % 1000;
+long long millions = (l/1000000) % 1000;
+long long billions = (l/1000000000) % 1000;
+long long trillions = l/1000000000000LL;
 if (l >= 1000000000000LL)
-    {
-    trillions = l/1000000000000LL;
-    l -= trillions * 1000000000000LL;
-    billions = l/1000000000;
-    l -= billions * 1000000000;
-    millions = l/1000000;
-    l -= millions * 1000000;
-    thousands = l/1000;
-    l -= thousands * 1000;
-    sprintf(s, "%lld,%03lld,%03lld,%03lld,%03lld", trillions, billions, millions, thousands, l);
-    }
+    sprintf(s, "%lld,%03lld,%03lld,%03lld,%03lld", trillions, billions, millions, thousands, ones);
 else if (l >= 1000000000)
-    {
-    billions = l/1000000000;
-    l -= billions * 1000000000;
-    millions = l/1000000;
-    l -= millions * 1000000;
-    thousands = l/1000;
-    l -= thousands * 1000;
-    sprintf(s, "%lld,%03lld,%03lld,%03lld", billions, millions, thousands, l);
-    }
+    sprintf(s, "%lld,%03lld,%03lld,%03lld", billions, millions, thousands, ones);
 else if (l >= 1000000)
-    {
-    millions = l/1000000;
-    l -= millions * (long long)1000000;
-    thousands = l/1000;
-    l -= thousands * 1000;
-    sprintf(s, "%lld,%03lld,%03lld", millions, thousands, l);
-    }
+    sprintf(s, "%lld,%03lld,%03lld", millions, thousands, ones);
 else if (l >= 1000)
-    {
-    thousands = l/1000;
-    l -= thousands * 1000;
-    sprintf(s, "%lld,%03lld", thousands, l);
-    }
+    sprintf(s, "%lld,%03lld", thousands, ones);
 else
     sprintf(s, "%lld", l);
 }
 
 void printLongWithCommas(FILE *f, long long l)
 /* Print out a long number with commas at thousands, millions, etc. */
 {
 char ascii[32];
 sprintLongWithCommas(ascii, l);
 fprintf(f, "%s", ascii);
 }
 
 void sprintWithGreekByte(char *s, int slength, long long size)
 /* Numbers formatted with PB, TB, GB, MB, KB, B */
 {