9c25510eb2cbb183c4e630d3519c693d33672dec
angie
  Mon Jul 18 16:59:07 2016 -0700
dbSNP includes some deletions >1kbp so just clone the reference allele instead of trying to copy into finite-size char[].  However, abbreviate really long alleles for display so they don't mess up the page.  refs #10937.

diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 739c2c6..c1276d6 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -16999,64 +16999,76 @@
     char **row;
     char query[512];
     sqlSafef(query, sizeof(query),
           "select chimpAllele from %s where name='%s'", orthoTable, rsId);
     sr = sqlGetResult(conn, query);
     if ((row = sqlNextRow(sr)) != NULL)
 	printf("<B>Summary: </B>%s>%s (chimp allele displayed first, "
 	       "then '>', then human alleles)<br>\n", row[0], observed);
     sqlFreeResult(&sr);
     hFreeConn(&conn);
     }
 }
 
 #define FOURBLANKCELLS "<TD></TD><TD></TD><TD></TD><TD></TD>"
 
+static char *abbreviateAllele(char *allele)
+/* If allele is >50bp then return an abbreviated version with first & last 20 bases and length;
+ * otherwise just return (cloned) allele. */
+{
+int length = strlen(allele);
+if (length > 50)
+    {
+    struct dyString *dyAbbr = dyStringCreate("%.20s", allele);
+    dyStringAppend(dyAbbr, "...");
+    dyStringAppend(dyAbbr, allele+length - 20);
+    dyStringPrintf(dyAbbr, " (%d bases)", length);
+    return dyStringCannibalize(&dyAbbr);
+    }
+return cloneString(allele);
+}
+
 void printSnpAlleleRows(struct snp125 *snp, int version)
 /* Print the UCSC ref allele (and dbSNP if it differs), as row(s) of a
  * 6-column table. */
 {
 if (sameString(snp->strand,"+") ||
     strchr(snp->refUCSC, '(')) // don't try to revComp refUCSC if it is "(N bp insertion)" etc.
     {
     printf("<TR><TD><B>Reference allele:&nbsp;</B></TD>"
-	   "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", snp->refUCSC);
+	   "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", abbreviateAllele(snp->refUCSC));
     if (!sameString(snp->refUCSC, snp->refNCBI))
 	printf("<TR><TD><B>dbSnp reference allele:&nbsp;</B></TD>"
-	       "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", snp->refNCBI);
+	       "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", abbreviateAllele(snp->refNCBI));
     }
 else if (sameString(snp->strand,"-"))
     {
-    char refUCSCRevComp[1024];
-    if (sameString(snp->strand, "-"))
-	{
-	safef(refUCSCRevComp, sizeof(refUCSCRevComp), "%s", snp->refUCSC);
+    char *refUCSCRevComp = cloneString(snp->refUCSC);
     reverseComplement(refUCSCRevComp, strlen(refUCSCRevComp));
-	}
     printf("<TR><TD><B>Reference allele:&nbsp;</B></TD>"
-	   "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", refUCSCRevComp);
+	   "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", abbreviateAllele(refUCSCRevComp));
     if (version < 127 && !sameString(refUCSCRevComp, snp->refNCBI))
 	printf("<TR><TD><B>dbSnp reference allele:&nbsp;</B></TD>"
-	       "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", snp->refNCBI);
+	       "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n", abbreviateAllele(snp->refNCBI));
     else if (version >= 127 && !sameString(snp->refUCSC, snp->refNCBI))
 	{
-	char refNCBIRevComp[1024];
-	safecpy(refNCBIRevComp, sizeof(refNCBIRevComp), snp->refNCBI);
+	char *refNCBIRevComp = cloneString(snp->refNCBI);
+        if (! strchr(snp->refNCBI, '('))
             reverseComplement(refNCBIRevComp, strlen(refNCBIRevComp));
 	printf("<TR><TD><B>dbSnp reference allele:&nbsp;</B></TD>"
 	       "<TD align=center>%s</TD>"FOURBLANKCELLS"</TR>\n",
-	       refNCBIRevComp);
+	       abbreviateAllele(refNCBIRevComp));
 	}
     }
 }
 
 #define TINYPADDING 3
 void printSnpOrthoOneRow(char *orthoName, char *orthoDb,
 			 char *orthoAllele, char *orthoStrand,
 			 char *orthoChrom, int orthoStart, int orthoEnd)
 /* Print out a 6-column table row describing an orthologous allele. */
 {
 printf("<TR><TD><B>%s allele:&nbsp;</B></TD>"
        "<TD align=center>%s</TD>\n", orthoName, orthoAllele);
 if (!sameString(orthoAllele, "?"))
     {
     printf("<TD>&nbsp;&nbsp;&nbsp;<B>%s strand:&nbsp;</B></TD>"
@@ -17296,44 +17308,42 @@
 else if (offset == 0)
     dyStringPrintf(dy, "<B>%c</B>%c%c", codon[0], codon[1], codon[2]);
 else if (offset == 1)
     dyStringPrintf(dy, "%c<B>%c</B>%c", codon[0], codon[1], codon[2]);
 else if (offset == 2)
     dyStringPrintf(dy, "%c%c<B>%c</B>", codon[0], codon[1], codon[2]);
 else
     dyStringAppend(dy, codon);
 return dy->string;
 }
 
 void printSnp125FunctionInCDS(struct snp125 *snp, char *geneTable, char *geneTrack,
 			      struct genePred *gene, int exonIx, char *geneName)
 /* Show the effect of each observed allele of snp on the given exon of gene. */
 {
-char refAllele[1024];
-safecpy(refAllele, sizeof(refAllele), snp->refUCSC);
+char *refAllele = cloneString(snp->refUCSC);
 boolean refIsAlpha = isalpha(refAllele[0]);
 boolean geneIsRc = sameString(gene->strand, "-"), snpIsRc = sameString(snp->strand, "-");
 if (geneIsRc && refIsAlpha)
     reverseComplement(refAllele, strlen(refAllele));
 int refAlleleSize = sameString(refAllele, "-") ? 0 : refIsAlpha ? strlen(refAllele) : -1;
 boolean refIsSingleBase = (refAlleleSize == 1 && refIsAlpha);
 int snpCodonPos = 0;
 char refCodon[4], refAA = '\0';
 if (refIsSingleBase)
     getSnp125RefCodonAndSnpPos(snp, gene, exonIx, &snpCodonPos, refCodon, &refAA);
-char alleleStr[1024];
-safecpy(alleleStr, sizeof(alleleStr), snp->observed);
+char *alleleStr = cloneString(snp->observed);
 char *indivAlleles[64];
 int alleleCount = chopString(alleleStr, "/", indivAlleles, ArraySize(indivAlleles));
 int j;
 for (j = 0;  j < alleleCount;  j++)
     {
     char *al = indivAlleles[j];
     boolean alIsAlpha = (isalpha(al[0]) && !sameString(al, "lengthTooLong"));
     if ((snpIsRc ^ geneIsRc) && alIsAlpha)
 	reverseComplement(al, strlen(al));
     char alBase = al[0];
     if (alBase == '\0' || sameString(al, refAllele))
 	continue;
     int alSize = sameString(al, "-") ? 0 : alIsAlpha ? strlen(al) : -1;
     if (alSize != refAlleleSize && alSize >= 0 && refAlleleSize >=0)
 	{
@@ -17378,31 +17388,32 @@
 	    }
 	else
 	    {
 	    if (refAA == '*')
 		printf(firstTwoColumnsPctS "%s %c (%s) --> %c (%s)\n",
 		       geneTrack, geneName, snpMisoLinkFromFunc("stop_retained_variant"),
 		       refAA, refCodonHtml, snpAA, snpCodonHtml);
 	    else
 		printf(firstTwoColumnsPctS "%s %c (%s) --> %c (%s)\n",
 		       geneTrack, geneName, snpMisoLinkFromFunc("coding-synon"),
 		       refAA, refCodonHtml, snpAA, snpCodonHtml);
 	    }
 	}
     else
 	printf(firstTwoColumnsPctS "%s %s --> %s\n",
-	       geneTrack, geneName, snpMisoLinkFromFunc("cds-synonymy-unknown"), refAllele, al);
+	       geneTrack, geneName, snpMisoLinkFromFunc("cds-synonymy-unknown"),
+               abbreviateAllele(refAllele), abbreviateAllele(al));
     }
 }
 
 void printSnp125FunctionInGene(struct snp125 *snp, char *geneTable, char *geneTrack,
 			       struct genePred *gene)
 /* Given a SNP and a gene that overlaps it, say where in the gene it overlaps
  * and if in CDS, say what effect the coding alleles have. */
 {
 int snpStart = snp->chromStart, snpEnd = snp->chromEnd;
 int cdsStart = gene->cdsStart, cdsEnd = gene->cdsEnd;
 boolean geneIsRc = sameString(gene->strand, "-");
 char *geneName = getSymbolForGeneName(geneTable, gene->name);
 int i, iStart = 0, iEnd = gene->exonCount, iIncr = 1;
 if (geneIsRc)
     { iStart = gene->exonCount - 1;  iEnd = -1;  iIncr = -1; }