06348905fb820c091e8d1c144c4fb39089a9a22e
galt
  Tue Jul 31 16:55:13 2012 -0700
hgc - cleaned up code with simpler, more reliable approach.
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 12b1ed4..540d5b2 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -293,46 +293,34 @@
 char *cloneDbScript = "http://www.ncbi.nlm.nih.gov/clone?term=";
 char *traceScript = "http://www.ncbi.nlm.nih.gov/Traces/trace.cgi?cmd=retrieve&val=";
 char *genMapDbScript = "http://genomics.med.upenn.edu/perl/genmapdb/byclonesearch.pl?clone=";
 char *uniprotFormat = "http://www.uniprot.org/uniprot/%s";
 
 /* variables for gv tables */
 char *gvPrevCat = NULL;
 char *gvPrevType = NULL;
 
 /* initialized by getCtList() if necessary: */
 struct customTrack *theCtList = NULL;
 
 /* getDNA stuff actually works when the database doesn't exist! */
 boolean dbIsFound = FALSE;
 
-/* was cartHtmlStart done?  */
-static boolean didCartHtmlStart = FALSE;
-static boolean plainTextDump = FALSE;
-
 /* forwards */
 char *getPredMRnaProtSeq(struct genePred *gp);
 void doAltGraphXDetails(struct trackDb *tdb, char *item);
 
-void hgcStart(char *title)
-/* Print out header of web page with title.  Set
- * error handler to normal html error handler. */
-{
-cartHtmlStart(title);
-didCartHtmlStart = TRUE;
-}
-
 char* getEntrezNucleotideUrl(char *accession)
 /* get URL for Entrez browser on a nucleotide. free resulting string */
 {
 char url[512];
 safef(url, sizeof(url), entrezFormat, "Nucleotide", accession, "GenBank");
 return cloneString(url);
 }
 
 void printEntrezNucleotideUrl(FILE *f, char *accession)
 /* Print URL for Entrez browser on a nucleotide. */
 {
 fprintf(f, entrezFormat, "Nucleotide", accession, "GenBank");
 }
 
 void printEntrezEstUrl(FILE *f, char *accession)
@@ -866,31 +854,30 @@
     printf("Size: %d   \n", otherEnd - otherStart);
     printBand( otherChrom, otherStart, otherEnd, FALSE);
 
     printf("<BR>\n");
     }
 }
 
 
 void genericHeader(struct trackDb *tdb, char *item)
 /* Put up generic track info. */
 {
 if (item != NULL && item[0] != 0)
     cartWebStart(cart, database, "%s (%s)", tdb->longLabel, item);
 else
     cartWebStart(cart, database, "%s", tdb->longLabel);
-didCartHtmlStart = TRUE;
 }
 
 static struct dyString *subMulti(char *orig, int subCount,
                                  char *in[], char *out[])
 /* Perform multiple substitions on orig. */
 {
 int i;
 struct dyString *s = newDyString(256), *d = NULL;
 
 dyStringAppend(s, orig);
 for (i=0; i<subCount; ++i)
     {
     d = dyStringSub(s->string, in[i], out[i]);
     dyStringFree(&s);
     s = d;
@@ -4605,33 +4592,32 @@
 char *action = cgiUsualString("submit", "");
 int itemCount;
 char *pos = NULL;
 char *chrom = NULL;
 int start = 0;
 int end = 0;
 
 if (sameString(action, EXTENDED_DNA_BUTTON))
     {
     doGetDnaExtended1();
     return;
     }
 // This output probably should be just text/plain but
 // trying to support the fancy warn handler box requires html.
 // But we want to keep it very simple and close to a plain text dump.
-plainTextDump = TRUE;
-puts("<html><head></head><body>\n");
-pushWarnHandler(htmlVaWarn);
+
+cartHtmlStart("DNA");
 hgBotDelay();
 puts("<PRE>");
 if (tbl[0] == 0)
     {
     itemCount = 1;
     if ( NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))) &&
          hgParseChromRange((dbIsFound ? database : NULL), pos, &chrom, &start, &end))
         {
         hgSeqRange(database, chrom, start, end, '?', "dna");
         }
     else
         {
         hgSeqRange(database, seqName, cartInt(cart, "l"), cartInt(cart, "r"),
                    '?', "dna");
         }
@@ -4668,32 +4654,30 @@
 	char buf[256];
 	if ((hti->nameField[0] != 0) && (item[0] != 0))
 	    {
 	    char *quotedItem = makeQuotedString(item, '\'');
 	    safef(buf, sizeof(buf), "%s = %s", hti->nameField, quotedItem);
 	    where = buf;
 	    freeMem(quotedItem);
 	    }
 	itemCount = hgSeqItemsInRange(database, tbl, seqName, start, end, where);
 	}
     }
 if (itemCount == 0)
     printf("\n# No results returned from query.\n\n");
 
 puts("</PRE>");
-puts("</body></html>\n");
-popWarnHandler();
 }
 
 struct hTableInfo *ctToHti(struct customTrack *ct)
 /* Create an hTableInfo from a customTrack. */
 {
 struct hTableInfo *hti;
 
 AllocVar(hti);
 hti->rootName = cloneString(ct->tdb->table);
 hti->isPos = TRUE;
 hti->isSplit = FALSE;
 hti->hasBin = FALSE;
 hti->type = cloneString(ct->tdb->type);
 int fieldCount = 3;
 if (sameWord(ct->dbTrackType, "bedDetail"))
@@ -5316,31 +5300,31 @@
     row = sqlNextRow(sr);
     if (row != NULL)
         imageId = sqlUnsigned(row[0]);
     sqlFreeResult(&sr);
     }
 return imageId;
 }
 
 void htcDisplayMrna(char *acc)
 /* Display mRNA available from genback or seq table.. */
 {
 struct dnaSeq *seq = hGenBankGetMrna(database, acc, NULL);
 if (seq == NULL)
     errAbort("mRNA sequence %s not found", acc);
 
-hgcStart("mRNA sequence");
+cartHtmlStart("mRNA sequence");
 printf("<PRE><TT>");
 faWriteNext(stdout, seq->name, seq->dna, seq->size);
 printf("</TT></PRE>");
 dnaSeqFree(&seq);
 }
 
 static int getEstTranscriptionDir(struct sqlConnection *conn, struct psl *psl)
 /* get the direction of transcription for an EST; return splice support count */
 {
 char query[256], estOrient[64];
 safef(query, sizeof(query),
       "select intronOrientation from %s.estOrientInfo where chrom = '%s' and chromStart = %d and name = '%s'",
       database, psl->tName, psl->tStart, psl->qName);
 if (sqlQuickQuery(conn, query, estOrient, sizeof(estOrient)) != NULL)
     return sqlSigned(estOrient) * ((psl->strand[0] == '+') ? 1 : -1);
@@ -7883,52 +7867,52 @@
 void displayProteinPrediction(char *pepName, char *pepSeq)
 /* display a protein prediction. */
 {
 printf("<PRE><TT>");
 printf(">%s length=%d\n", pepName,(int)strlen(pepSeq));
 printLines(stdout, pepSeq, 50);
 printf("</TT></PRE>");
 }
 
 void htcTranslatedProtein(char *pepName)
 /* Display translated protein. */
 {
 char *table = cartString(cart, "o");
 /* checks both gbSeq and table */
 aaSeq *seq = hGenBankGetPep(database, pepName, table);
-hgcStart("Protein Translation");
+cartHtmlStart("Protein Translation");
 if (seq == NULL)
     {
     warn("Predicted peptide %s is not avaliable", pepName);
     }
 else
     {
     displayProteinPrediction(pepName, seq->dna);
     dnaSeqFree(&seq);
     }
 }
 
 void htcTranslatedPredMRna(struct trackDb *tdb, char *geneName)
 /* Translate virtual mRNA defined by genePred to protein and display it. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct genePred *gp = NULL;
 char where[256];
 char protName[256];
 char *prot = NULL;
 
-hgcStart("Protein Translation from Genome");
+cartHtmlStart("Protein Translation from Genome");
 safef(where, sizeof(where), "name = \"%s\"", geneName);
 gp = genePredReaderLoadQuery(conn, tdb->table, where);
 hFreeConn(&conn);
 if (gp == NULL)
     errAbort("%s not found in %s when translating to protein",
              geneName, tdb->table);
 else if (gp->cdsStart == gp->cdsEnd)
     errAbort("No CDS defined: no protein translation for %s", geneName);
 prot = getPredMRnaProtSeq(gp);
 safef(protName, sizeof(protName), "%s_prot", geneName);
 displayProteinPrediction(protName, prot);
 
 freez(&prot);
 genePredFree(&gp);
 }
@@ -7938,31 +7922,31 @@
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct genbankCds cds = getCds(conn, acc);
 struct dnaSeq *mrna = hGenBankGetMrna(database, acc, NULL);
 if (mrna == NULL)
     errAbort("mRNA sequence %s not found", acc);
 if (cds.end > mrna->size)
     errAbort("CDS bounds exceed length of mRNA for %s", acc);
 
 int protBufSize = ((cds.end-cds.start)/3)+4;
 char *prot = needMem(protBufSize);
 
 mrna->dna[cds.end] = '\0';
 dnaTranslateSome(mrna->dna+cds.start, prot, protBufSize);
 
-hgcStart("Protein Translation of mRNA");
+cartHtmlStart("Protein Translation of mRNA");
 displayProteinPrediction(acc, prot);
 }
 
 void getCdsInMrna(struct genePred *gp, int *retCdsStart, int *retCdsEnd)
 /* Given a gene prediction, figure out the
  * CDS start and end in mRNA coordinates. */
 {
 int missingStart = 0, missingEnd = 0;
 int exonStart, exonEnd, exonSize, exonIx;
 int totalSize = 0;
 
 for (exonIx = 0; exonIx < gp->exonCount; ++exonIx)
     {
     exonStart = gp->exonStarts[exonIx];
     exonEnd = gp->exonEnds[exonIx];
@@ -8068,31 +8052,31 @@
 }
 
 void htcGeneMrna(char *geneName)
 /* Display cDNA predicted from genome */
 {
 char *table = cartString(cart, "o");
 char query[512];
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr;
 char **row;
 struct genePred *gp;
 struct dnaSeq *seq;
 int cdsStart, cdsEnd;
 int rowOffset = hOffsetPastBin(database, seqName, table);
 
-hgcStart("Predicted mRNA from Genome");
+cartHtmlStart("Predicted mRNA from Genome");
 safef(query, sizeof(query), "select * from %s where name = \"%s\"", table, geneName);
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     gp = genePredLoad(row+rowOffset);
     seq = getCdnaSeq(gp);
     getCdsInMrna(gp, &cdsStart, &cdsEnd);
     toUpperN(seq->dna + cdsStart, cdsEnd - cdsStart);
     if (gp->strand[0] == '-')
 	{
         reverseComplement(seq->dna, seq->size);
 	}
     printf("<PRE><TT>");
     printf(">%s\n", geneName);
     faWriteNext(stdout, NULL, seq->dna, seq->size);
@@ -8100,31 +8084,31 @@
     genePredFree(&gp);
     freeDnaSeq(&seq);
     }
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 }
 
 void htcRefMrna(char *geneName)
 /* Display mRNA associated with a refSeq gene. */
 {
 /* check both gbSeq and refMrna */
 struct dnaSeq *seq = hGenBankGetMrna(database, geneName, "refMrna");
 if (seq == NULL)
     errAbort("RefSeq mRNA sequence %s not found", geneName);
 
-hgcStart("RefSeq mRNA");
+cartHtmlStart("RefSeq mRNA");
 printf("<PRE><TT>");
 faWriteNext(stdout, seq->name, seq->dna, seq->size);
 printf("</TT></PRE>");
 dnaSeqFree(&seq);
 }
 
 void cartContinueRadio(char *var, char *val, char *defaultVal)
 /* Put up radio button, checking it if it matches val */
 {
 char *oldVal = cartUsualString(cart, var, defaultVal);
 cgiMakeRadioButton(var, val, sameString(oldVal, val));
 }
 
 void htcGeneInGenome(char *geneName)
 /* Put up page that lets user display genomic sequence
@@ -12706,31 +12690,31 @@
 	htmlHorizontalLine();
 	}
     }
 else
     {
     puts("<P>Click directly on a repeat for specific information on that repeat</P>");
     }
 printTrackHtml(tdb);
 hFreeConn(&conn);
 }
 
 void htcExtSeq(char *item)
 /* Print out DNA from some external but indexed .fa file. */
 {
 struct dnaSeq *seq;
-hgcStart(item);
+cartHtmlStart(item);
 seq = hExtSeq(database, item);
 printf("<PRE><TT>");
 faWriteNext(stdout, item, seq->dna, seq->size);
 printf("</TT></PRE>");
 freeDnaSeq(&seq);
 }
 
 void doBlatMouse(struct trackDb *tdb, char *itemName)
 /* Handle click on blatMouse track. */
 {
 char query[256];
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr = NULL;
 char **row;
 int start = cartInt(cart, "o");
@@ -25351,34 +25335,31 @@
 else if (sameString("geneReviews", table))
     {
     doGeneReviews(tdb, item);
     }
 else if (tdb != NULL)
     {
     genericClickHandler(tdb, item, NULL);
     }
 else
     {
     cartWebStart(cart, database, "%s", track);
     printf("Sorry, clicking there doesn't do anything yet (%s).", track);
     }
 /* End of 1000+ line dispatch on table involving 100+ if/elses. */
 
-if (didCartHtmlStart)
     cartHtmlEnd();
-else if (!plainTextDump)
-    webEnd();
 }
 
 struct hash *orgDbHash = NULL;
 
 void initOrgDbHash()
 /* Function to initialize a hash of organism names that hash to a database ID.
  * This is used to show alignments by hashing the organism associated with the
  * track to the database name where the chromInfo is stored. For example, the
  * mousBlat track in the human browser would hash to the mm2 database. */
 {
 orgDbHash = hashNew(8);
 }
 
 void cartDoMiddle(struct cart *theCart)
 /* Save cart and do main middle handler. */