src/utils/raSqlQuery/raSqlQuery.c 1.5

1.5 2009/11/20 04:39:16 kent
Making wildcards (other than the single ?) work in field specs.
Index: src/utils/raSqlQuery/raSqlQuery.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/utils/raSqlQuery/raSqlQuery.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -B -U 4 -r1.4 -r1.5
--- src/utils/raSqlQuery/raSqlQuery.c	20 Nov 2009 01:52:43 -0000	1.4
+++ src/utils/raSqlQuery/raSqlQuery.c	20 Nov 2009 04:39:16 -0000	1.5
@@ -1,8 +1,9 @@
 /* raSqlQuery - Do a SQL-like query on a RA file.. */
 #include "common.h"
 #include "linefile.h"
 #include "hash.h"
+#include "dystring.h"
 #include "options.h"
 #include "obscure.h"
 #include "ra.h"
 #include "localmem.h"
@@ -467,8 +468,47 @@
 {
 return rqlParseCmp(tkz);
 }
 
+char *rqlParseFieldSpec(struct tokenizer *tkz, struct dyString *buf)
+/* Return a field spec, which may contain * and ?. Put results in buf, and 
+ * return buf->string. */
+{
+boolean firstTime = TRUE;
+dyStringClear(buf);
+for (;;)
+   {
+   char *tok = tokenizerNext(tkz);
+   if (tok == NULL)
+       break;
+   char c = *tok;
+   if (c == '?' || c == '*' || isalpha(c) || c == '_')
+       {
+       if (firstTime)
+	   dyStringAppend(buf, tok);
+       else
+           {
+	   if (tkz->leadingSpaces == 0)
+	       dyStringAppend(buf, tok);
+	   else
+	       {
+	       tokenizerReuse(tkz);
+	       break;
+	       }
+	   }
+       }
+   else
+       {
+       tokenizerReuse(tkz);
+       break;
+       }
+    firstTime = FALSE;
+    }
+if (buf->stringSize == 0)
+    errAbort("Expecting field name line %d of %s", tkz->lf->lineIx, tkz->lf->fileName);
+return buf->string;
+}
+
 void rqlStatementDump(struct rqlStatement *rql, FILE *f)
 /* Print out statement to file. */
 {
 fprintf(f, "%s", rql->command);
@@ -721,10 +761,11 @@
 AllocVar(rql);
 rql->command = cloneString(tokenizerMustHaveNext(tkz));
 if (sameString(rql->command, "select"))
     {
+    struct dyString *buf = dyStringNew(0);
     struct slName *list = NULL;
-    char *tok = tokenizerMustHaveNext(tkz);
+    char *tok = rqlParseFieldSpec(tkz, buf);
     list = slNameNew(tok);
     for (;;)
 	{
 	/* Parse out comma-separated field list. */
@@ -733,12 +774,13 @@
 	    {
 	    tokenizerReuse(tkz);
 	    break;
 	    }
-	struct slName *field = slNameAddHead(&list, tokenizerMustHaveNext(tkz));
+	struct slName *field = slNameAddHead(&list, rqlParseFieldSpec(tkz, buf));
 	}
     slReverse(&list);
     rql->fieldList = list;
+    dyStringFree(&buf);
     }
 else if (sameString(rql->command, "count"))
     {
     /* No parameters to count. */