e705ce240cb855d55092b6b80c8f2dec1822aa74
max
  Wed Feb 17 02:08:30 2021 -0800
fixing various bugs in hgBlat json output, refs #27010

diff --git src/lib/psl.c src/lib/psl.c
index d438fda..3d4b4ae 100644
--- src/lib/psl.c
+++ src/lib/psl.c
@@ -172,100 +172,100 @@
 *pList = NULL;
 }
 
 void pslOutputJson(struct psl *el, FILE *f) 
 /* print out psl as a json array */
 {
 fputs("[", f);
 fprintf(f, "%u,", el->match);
 fprintf(f, "%u,", el->misMatch);
 fprintf(f, "%u,", el->repMatch);
 fprintf(f, "%u,", el->nCount);
 fprintf(f, "%u,", el->qNumInsert);
 fprintf(f, "%d,", el->qBaseInsert);
 fprintf(f, "%u,", el->tNumInsert);
 fprintf(f, "%d,", el->tBaseInsert);
-fprintf(f, "'%s',", el->strand);
-fprintf(f, "'%s',", el->qName);
+fprintf(f, "\"%s\",", el->strand);
+fprintf(f, "\"%s\",", el->qName);
 fprintf(f, "%u,", el->qSize);
 fprintf(f, "%u,", el->qStart);
 fprintf(f, "%u,", el->qEnd);
-fprintf(f, "'%s',", el->tName);
+fprintf(f, "\"%s\",", el->tName);
 fprintf(f, "%u,", el->tSize);
 fprintf(f, "%u,", el->tStart);
 fprintf(f, "%u,", el->tEnd);
 fprintf(f, "%u,", el->blockCount);
 
 fputs("[", f);
 for (int i=0; i<el->blockCount; ++i)
     {
     fprintf(f, "%u", el->blockSizes[i]);
-    if (i-1<el->blockCount)
+    if (i < el->blockCount-1)
         fputc(',', f);
     }
 fputs("]", f);
 fputs(",", f);
 
 fputs("[", f);
 for (int i=0; i<el->blockCount; ++i)
     {
     fprintf(f, "%u", el->qStarts[i]);
-    if (i-1<el->blockCount)
+    if (i < el->blockCount-1)
         fputc(',', f); // json does not allow trailing commas
     }
 fputs("]", f);
 fputs(",", f);
 
 fputs("[", f);
 for (int i=0; i<el->blockCount; ++i)
     {
     fprintf(f, "%u", el->tStarts[i]);
-    if (i-1<el->blockCount)
+    if (i < el->blockCount-1)
         fputc(',', f);
     }
 fputs("]", f);
 
 if (el->qSequence)
     {
     fputc(',',f);
     fputc('[',f);
     for (int i=0; i<el->blockCount; ++i)
 	{
 	fprintf(f, "'%s'", el->qSequence[i]);
-        if (i-1<el->blockCount)
+        if (i < el->blockCount-1)
             fputc(',', f);
 	}
     fputc(']',f);
     fputc(',',f);
 
     fputc('[',f);
     for (int i=0; i<el->blockCount; ++i)
 	{
-	fprintf(f, "%s", el->tSequence[i]);
-        if (i-1<el->blockCount)
+	fprintf(f, "\"%s\"", el->tSequence[i]);
+        if (i < el->blockCount-1)
             fputc(',', f);
 	}
     fputc(']',f);
     }
 
 if (ferror(f))
     {
     perror("Error writing psl file\n");
     errAbort("\n");
     }
 
-fputs("]\n", f);
+fputs("]", f);
 }
 
 void pslOutput(struct psl *el, FILE *f, char sep, char lastSep) 
 /* Print out psl.  Separate fields with sep. Follow last field with lastSep. */
 {
 int i;
 fprintf(f, "%u", el->match);
 fputc(sep,f);
 fprintf(f, "%u", el->misMatch);
 fputc(sep,f);
 fprintf(f, "%u", el->repMatch);
 fputc(sep,f);
 fprintf(f, "%u", el->nCount);
 fputc(sep,f);
 fprintf(f, "%u", el->qNumInsert);
@@ -541,33 +541,33 @@
 }
 
 static void pslLabelColumns(FILE *f)
 /* Write column info. */
 {
 fputs("\n"
 "match\tmis- \trep. \tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ        \tQ   \tQ    \tQ  \tT        \tT   \tT    \tT  \tblock\tblockSizes \tqStarts\t tStarts\n"
 "     \tmatch\tmatch\t   \tcount\tbases\tcount\tbases\t      \tname     \tsize\tstart\tend\tname     \tsize\tstart\tend\tcount\n" 
 "---------------------------------------------------------------------------------------------------------------------------------------------------------------\n",
 f);
 }
 
 static void pslLabelColumnsJson(FILE *f) 
 /* Write column info as a JSON array */
 {
-fputs("['matches', 'misMatches', 'repMatches', 'nCount', 'qNumInsert', 'qBaseInsert', "
-        "'tNumInsert', 'tBaseInsert', 'strand', 'qName', 'qSize', 'qStart', 'qEnd', 'tName', "
-        "'tSize', 'tEnd', 'blockCount', 'blockSizes', 'qStarts', 'tStarts]", f);
+fputs("[\"matches\", \"misMatches\", \"repMatches\", \"nCount\", \"qNumInsert\", \"qBaseInsert\", "
+        "\"tNumInsert\", \"tBaseInsert\", \"strand\", \"qName\", \"qSize\", \"qStart\", \"qEnd\", \"tName\", "
+        "\"tSize\", \"tEnd\", \"blockCount\", \"blockSizes\", \"qStarts\", \"tStarts\"]", f);
 }
 
 void pslxWriteHead(FILE *f, enum gfType qType, enum gfType tType)
 /* Write header for extended (possibly protein) psl file. */
 {
 fprintf(f, "psLayout version 4 %s %s\n", gfTypeName(qType), gfTypeName(tType));
 pslLabelColumns(f);
 }
 
 void pslWriteHead(FILE *f)
 /* Write head of psl. */
 {
 fputs("psLayout version 3\n", f);
 pslLabelColumns(f);
 }
@@ -589,31 +589,31 @@
 void pslWriteAllJson(struct psl *pslList, FILE *f, boolean writeHeader)
 /* Write a psl file from list as a json array . */
 {
 fputs("[\n", f);
 if (writeHeader)
     pslLabelColumnsJson(f);
 fputs(",\n", f);
 
 for (struct psl *psl = pslList; psl; psl = psl->next)
     {
     pslOutputJson(psl, f);
     if (psl->next)
         fputs(",\n", f);
     }
 
-puts("]\n");
+puts("\n]\n");
 }
 
 void pslxFileOpen(char *fileName, enum gfType *retQueryType, enum gfType *retTargetType, struct lineFile **retLf)
 /* Read header part of psl and make sure it's right.  Return
  * sequence types and file handle. */
 {
 char *line;
 int lineSize;
 char *words[30];
 char *version;
 int wordCount;
 int i;
 enum gfType qt = gftRna,  tt = gftDna;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);