bc9bf742e89a5fcbe6bc6f164a15516d1c01a4fc
kent
  Thu Aug 8 12:17:48 2013 -0700
Got output to compile.  Added a test script.
diff --git src/utils/raToStructGen/raToStructGen.c src/utils/raToStructGen/raToStructGen.c
index 3cab43c..2390794 100644
--- src/utils/raToStructGen/raToStructGen.c
+++ src/utils/raToStructGen/raToStructGen.c
@@ -1,49 +1,52 @@
 /* raToStructGen - Write C code that will read/write a C structure from a ra file.. */
 #include "common.h"
 #include "linefile.h"
 #include "hash.h"
 #include "options.h"
 #include "obscure.h"
 #include "sqlNum.h"
 #include "ra.h"
 #include "asParse.h"
 
 /* Command line globals. */
 char *requiredAsComma = NULL;
 char *computedAsComma = NULL;
+boolean testMain = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "raToStructGen - Write C code that will read/write a C structure from a ra file.\n"
   "In some ways a poor cousin to AutoSql. Only handles numeric and string types, and\n"
   "arrays of these.\n"
   "usage:\n"
   "   raToStructGen guide.as output.c\n"
   "options:\n"
   "   -required=comma,sep,list - comma separated list of required fields.\n"
   "   -computed=comma,sep,list - comma separated list of fields that are computed not parsed\n"
   "                              These fields will be ignored if in input\n"
+  "   -testMain - generate a main() routine to help test\n"
   );
 }
 
 /* Command line validation table. */
 static struct optionSpec options[] = {
    {"required", OPTION_STRING},
    {"computed", OPTION_STRING},
+   {"testMain", OPTION_BOOLEAN},
    {NULL, 0},
 };
 
 struct raToStructReader
 /* Something to help us parse RAs into C structures. */
     {
     struct raToStructReader *next;
     char *name;		      /* Name of structure */
     int fieldCount;	      /* Number of fields. */
     char **fields;	      /* Names of all fields - not allocated here. */
     char **requiredFields;    /* Names of required fields - not allocated here */
     int requiredFieldCount;   /* Count of required fields. */
     struct hash *fieldIds;    /* So we can do hashLookup/switch instead of strcmp chain */
     int *requiredFieldIds;    /* An array of IDs of required fields. */
     bool *fieldsObserved;  /* An entry for each field we've observed. */
@@ -105,67 +108,104 @@
 /* Make sure that all required files have been seen in the stanza we just parsed. */
 {
 int *requiredFieldIds = reader->requiredFieldIds;
 bool *fieldsObserved = reader->fieldsObserved;
 int i;
 for (i=0; i<reader->requiredFieldCount; ++i)
     {
     if (!fieldsObserved[requiredFieldIds[i]])
 	{
 	errAbort("Required field %s not found line %d of %s", reader->requiredFields[i],
 	    lf->lineIx, lf->fileName);
 	}
     }
 }
 
+void addTestMain(FILE *f, struct asObject *as)
+/* Print out a main routine that will do a little testing. */
+{
+fprintf(f, 
+"int main(int argc, char *argv[])\n"
+"/* Process command line and test. */\n"
+"{\n"
+"if (argc != 2)\n"
+"    errAbort(\"expecting exactly one command line argument\");\n"
+"struct %s *list = %sLoadRa(argv[1]);\n"
+"printf(\"Got %%d elements in %%s\\n\", slCount(list), argv[1]);\n"
+"return 0;\n"
+"}\n"
+"\n"
+, as->name, as->name);
+}
+
 void raToStructGen(char *guideFile, char *outFileC)
 /* raToStructGen - Write C code that will read/write a C structure from a ra file. */
 {
 struct hash *ignoreHash = hashNew(0);
 
+/* Convert comma separated computeAsComma list to ignoreHash */
 int computedCount = 0;
 if (computedAsComma != NULL)
     {
     if (lastChar(computedAsComma) == ',')
         trimLastChar(computedAsComma);
     computedCount = chopByChar(computedAsComma, ',', NULL, 0);
     char **computedFields = NULL;
     AllocArray(computedFields, computedCount);
     chopByChar(computedAsComma, ',', computedFields, computedCount);
     int i;
     for (i=0; i<computedCount; ++i)
         hashAdd(ignoreHash, computedFields[i], NULL);
     }
 
+/* Parse through requiredAsComma */
 int requiredCount = 0;
 char **requiredFields = NULL;
 if (requiredAsComma != NULL)
     {
     if (lastChar(requiredAsComma) == ',')
         trimLastChar(requiredAsComma);
     requiredCount = chopByChar(requiredAsComma, ',', NULL, 0);
     AllocArray(requiredFields, requiredCount);
     chopByChar(requiredAsComma, ',', requiredFields, requiredCount);
     }
 struct asObject *as = asParseFile(guideFile);
 if (as == NULL)
     errAbort("Nothing in %s", guideFile);
 if (as->next != NULL)
     errAbort("Multiple objects in %s, only one allowed", guideFile);
 
 FILE *f = mustOpen(outFileC, "w");
 
+/* Print out header. */
+fprintf(f, 
+"/* Parser to read in a %s from a ra file where tags in ra file correspond to fields in a\n"
+" * struct. This program was generated by raToStructGen. */\n"
+"\n"
+"#include \"common.h\"\n"
+"#include \"linefile.h\"\n"
+"#include \"hash.h\"\n"
+"#include \"obscure.h\"\n"
+"#include \"sqlNum.h\"\n"
+"#include \"sqlList.h\"\n"
+"#include \"ra.h\"\n"
+"#include \"raToStruct.h\"\n"
+, as->name);
+if (testMain)
+   fprintf(f, "#include \"testStruct.h\"\n");
+fprintf(f, "\n");
+
 /* Print out start of reader-maker function. */
 fprintf(f, 
     "struct raToStructReader *%sRaReader()\n"
     "/* Make a raToStructReader for %s */\n"
     "{\n"
     "static char *fields[] = {\n"
     , as->name, as->name);
 
 /* Print out all field names */
 struct asColumn *col;
 for (col = as->columnList; col != NULL; col = col->next)
     if (!skipColumn(col, ignoreHash))
 	fprintf(f, "    \"%s\",\n", col->name);
 fprintf(f, "    };\n");
 
@@ -345,32 +385,36 @@
 /* Print out single record reader. */
 fprintf(f,
 "struct %s *%sOneFromRa(char *fileName)\n"
 "/* Return %s in file and insist there be exactly one record. */\n"
 "{\n"
 "struct %s *one = %sLoadRa(fileName);\n"
 "if (one == NULL)\n"
 "    errAbort(\"No data in %%s\", fileName);\n"
 "if (one->next != NULL)\n"
 "    errAbort(\"Multiple records in %%s\", fileName);\n"
 "return one;\n"
 "}\n"
 "\n"
 , as->name, as->name, as->name, as->name, as->name);
 
+if (testMain)
+    addTestMain(f, as);
+
 
 carefulClose(&f);
 verbose(1, "Generated parser for %d required fields, %d computed fields, %d total fields\n", 
     requiredCount, computedCount, slCount(as->columnList));
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 if (argc != 3)
     usage();
 requiredAsComma = optionVal("required", NULL);
 computedAsComma = optionVal("computed", NULL);
+testMain = optionExists("testMain");
 raToStructGen(argv[1], argv[2]);
 return 0;
 }