533112afe2a2005e80cdb1f82904ea65032d4302
braney
  Sat Oct 2 11:37:34 2021 -0700
split hg/lib into two separate libaries, one only used by the cgis

diff --git src/hg/cgilib/pcrResult.c src/hg/cgilib/pcrResult.c
new file mode 100644
index 0000000..9d4f1e8
--- /dev/null
+++ src/hg/cgilib/pcrResult.c
@@ -0,0 +1,214 @@
+/* pcrResult -- support for internal track of hgPcr results. */
+
+/* Copyright (C) 2014 The Regents of the University of California 
+ * See README in this or parent directory for licensing information. */
+
+#include "common.h"
+#include "hdb.h"
+#include "hui.h"
+#include "obscure.h"
+#include "targetDb.h"
+#include "pcrResult.h"
+
+
+char *pcrResultCartVar(char *db)
+/* Returns the cart variable name for PCR result track info for db. 
+ * Don't free the result! */
+{
+static char buf[1024];
+safef(buf, sizeof(buf), "%s_%s", PCR_RESULT_TRACK_NAME, db);
+return buf;
+}
+
+#define setPtIfNotNull(pt, val) if (pt != NULL) *pt = val
+
+boolean pcrResultParseCart(char *db, struct cart *cart, char **retPslFile,
+			   char **retPrimerFile,
+			   struct targetDb **retTarget)
+/* Parse out hgPcrResult cart variable into components and make sure
+ * they are valid.  If so, set *ret's and return TRUE.  Otherwise, null out 
+ * *ret's and return FALSE (and clear the cart variable if it exists).  
+ * ret's are ignored if NULL. */
+{
+char *cartVar = pcrResultCartVar(cartString(cart, "db"));
+char *hgPcrResult = cartOptionalString(cart, cartVar);
+if (isEmpty(hgPcrResult))
+    {
+    setPtIfNotNull(retPslFile, NULL);
+    setPtIfNotNull(retPrimerFile, NULL);
+    setPtIfNotNull(retTarget, NULL);
+    return FALSE;
+    }
+static char buf[2048];
+char *words[3];
+int wordCount;
+safecpy(buf, sizeof(buf), hgPcrResult);
+wordCount = chopLine(buf, words);
+if (wordCount < 2)
+    errAbort("Badly formatted hgPcrResult variable: %s", hgPcrResult);
+char *pslFile = words[0];
+char *primerFile = words[1];
+char *targetName = (wordCount > 2) ? words[2] : NULL;
+struct targetDb *target = NULL;
+if (isNotEmpty(targetName))
+    target = targetDbLookup(db, targetName);
+
+if (!fileExists(pslFile) || !fileExists(primerFile) ||
+    (wordCount > 2 && target == NULL))
+    {
+    cartRemove(cart, cartVar);
+    setPtIfNotNull(retPslFile, NULL);
+    setPtIfNotNull(retPrimerFile, NULL);
+    setPtIfNotNull(retTarget, NULL);
+    return FALSE;
+    }
+setPtIfNotNull(retPslFile, cloneString(pslFile));
+setPtIfNotNull(retPrimerFile, cloneString(primerFile));
+setPtIfNotNull(retTarget, target);
+if (retTarget == NULL)
+    targetDbFreeList(&target);
+return TRUE;
+}
+
+void pcrResultGetPrimers(char *fileName, char **retFPrimer, char **retRPrimer)
+/* Given a file whose first line is 2 words (forward primer, reverse primer)
+ * set the ret's to upper-cased primer sequences.  
+ * Do not free the statically allocated ret's. */
+{
+static char fPrimer[1024], rPrimer[1024];;
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+char *words[2];
+if (! lineFileRow(lf, words))
+    lineFileAbort(lf, "Couldn't read primers");
+if (retFPrimer != NULL)
+    {
+    safecpy(fPrimer, sizeof(fPrimer), words[0]);
+    touppers(fPrimer);
+    *retFPrimer = fPrimer;
+    }
+if (retRPrimer != NULL)
+    {
+    safecpy(rPrimer, sizeof(rPrimer), words[1]);
+    touppers(rPrimer);
+    *retRPrimer = rPrimer;
+    }
+lineFileClose(&lf);
+}
+
+void pcrResultGetPsl(char *fileName, struct targetDb *target, char *item,
+		     char *chrom, int itemStart, int itemEnd,
+		     struct psl **retItemPsl, struct psl **retOtherPsls)
+/* Read in psl from file.  If a psl matches the given item position, set 
+ * retItemPsl to that; otherwise add it to retOtherPsls.  Die if no psl
+ * matches the given item position. */
+{
+struct lineFile *lf = lineFileOpen(fileName, TRUE);
+struct psl *itemPsl = NULL, *otherPsls = NULL;
+char *pslFields[21];
+while (lineFileRow(lf, pslFields))
+    {
+    struct psl *psl = pslLoad(pslFields);
+    boolean gotIt = FALSE;
+    if (target != NULL)
+	{
+	if (sameString(psl->tName, item) && psl->tStart == itemStart && psl->tEnd == itemEnd)
+	    gotIt = TRUE;
+	}
+    else if (sameString(psl->tName, chrom) && psl->tStart == itemStart &&
+	     psl->tEnd == itemEnd)
+	gotIt = TRUE;
+    if (gotIt)
+	itemPsl = psl;
+    else
+	slAddHead(&otherPsls, psl);
+    }
+lineFileClose(&lf);
+if (itemPsl == NULL)
+    {
+    if (target != NULL)
+	errAbort("Did not find record for amplicon in %s sequence %s",
+		 target->description, item);
+    else
+	errAbort("Did not find record for amplicon at %s:%d-%d",
+		 chrom, itemStart, itemEnd);
+    }
+if (retItemPsl != NULL)
+    *retItemPsl = itemPsl;
+else
+    pslFree(&itemPsl);
+if (retOtherPsls != NULL)
+    {
+    slSort(&otherPsls, pslCmpTarget);
+    *retOtherPsls = otherPsls;
+    }
+else
+    pslFreeList(&otherPsls);
+}
+
+struct trackDb *pcrResultFakeTdb()
+/* Construct a trackDb record for PCR Results track. */
+{
+struct trackDb *tdb;
+AllocVar(tdb);
+tdb->track = cloneString(PCR_RESULT_TRACK_NAME);
+tdb->table = cloneString(PCR_RESULT_TRACK_NAME);
+tdb->shortLabel = cloneString(PCR_RESULT_TRACK_LABEL);
+tdb->longLabel = cloneString(PCR_RESULT_TRACK_LONGLABEL);
+tdb->grp = cloneString("map");
+tdb->type = cloneString("psl .");
+tdb->priority = 100.01;
+tdb->canPack = TRUE;
+tdb->visibility = tvPack;
+tdb->html = hFileContentsOrWarning(hHelpFile(PCR_RESULT_TRACK_NAME));
+trackDbPolish(tdb);
+if (tdb->settingsHash == NULL)
+    tdb->settingsHash = hashNew(0);
+hashAdd(tdb->settingsHash, BASE_COLOR_DEFAULT, cloneString("diffBases"));
+hashAdd(tdb->settingsHash, BASE_COLOR_USE_SEQUENCE,
+	cloneString(PCR_RESULT_TRACK_NAME));
+hashAdd(tdb->settingsHash, SHOW_DIFF_BASES_ALL_SCALES, cloneString("."));
+hashAdd(tdb->settingsHash, INDEL_DOUBLE_INSERT, cloneString("on"));
+hashAdd(tdb->settingsHash, INDEL_QUERY_INSERT, cloneString("on"));
+hashAdd(tdb->settingsHash, INDEL_POLY_A, cloneString("on"));
+hashAdd(tdb->settingsHash, "nextItemButton", cloneString("off"));
+return tdb;
+}
+
+char *pcrResultItemAccName(char *acc, char *name)
+/* If a display name is given in addition to the acc, concatenate them
+ * into a single name that must match a non-genomic target item's name
+ * in the targetDb .2bit.  Do not free the result. */
+{
+static char accName[256];
+if (isEmpty(name))
+    safecpy(accName, sizeof(accName), acc);
+else
+    safef(accName, sizeof(accName), "%s__%s", acc, name);
+return accName;
+}
+
+char *pcrResultItemAccession(char *nameIn)
+/* If nameIn contains a concatenated accession and display name, returns
+ * just the accession.  Do not free the result.*/
+{
+char *ptr = strstr(nameIn, "__");
+if (ptr != NULL)
+    {
+    static char nameOut[128];
+    safecpy(nameOut, sizeof(nameOut), nameIn);
+    nameOut[ptr-nameIn] = '\0';
+    return nameOut;
+    }
+return nameIn;
+}
+
+char *pcrResultItemName(char *nameIn)
+/* If nameIn contains a concatenated accession and display name, returns
+ * just the name.  If accession only, returns NULL.  Do not free the result.*/
+{
+char *ptr = strstr(nameIn, "__");
+if (ptr != NULL)
+    return ptr+2;
+return NULL;
+}
+