101c33cf32e9ce191cad2a8b333d473f2059fa7a kent Tue Sep 3 16:09:46 2013 -0700 Adding support for arrays, and also extraH option to raToStructGen. diff --git src/utils/raToStructGen/raToStructGen.c src/utils/raToStructGen/raToStructGen.c index 2390794..2e89faa 100644 --- src/utils/raToStructGen/raToStructGen.c +++ src/utils/raToStructGen/raToStructGen.c @@ -1,52 +1,55 @@ /* 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; +char *extraH = NULL; 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" + " -extraH=someFile.h - Path to an extra include file\n" ); } /* Command line validation table. */ static struct optionSpec options[] = { {"required", OPTION_STRING}, {"computed", OPTION_STRING}, {"testMain", OPTION_BOOLEAN}, + {"extraH", OPTION_STRING}, {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. */ @@ -75,31 +78,31 @@ { char *required = requiredFields[i]; struct hashEl *hel = hashLookup(fieldIds, required); if (hel == NULL) errAbort("Required field %s is not in field list", required); reader->requiredFieldIds[i] = ptToInt(hel->val); } } AllocArray(reader->fieldsObserved, fieldCount); return reader; } boolean skipColumn(struct asColumn *col, struct hash *ignoreHash) /* Return TRUE if we should skip column. */ { -return col->isSizeLink || hashLookup(ignoreHash, col->name) != NULL; +return hashLookup(ignoreHash, col->name) != NULL; } void raToStructReaderFree(struct raToStructReader **pReader) /* Free up memory associated with reader. */ { struct raToStructReader *reader = *pReader; if (reader != NULL) { freeMem(reader->name); freeHash(&reader->fieldIds); freeMem(reader->fieldIds); freeMem(reader->fieldsObserved); freez(pReader); } } @@ -178,30 +181,32 @@ /* 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 (extraH) + fprintf(f, "#include \"%s\"\n", extraH); 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) @@ -286,60 +291,69 @@ /* For all the types we'll handle, isList means an array. */ switch (type) { /* Handle numerical and string types */ case t_float: case t_double: case t_int: case t_uint: case t_short: case t_ushort: case t_off: case t_string: case t_lstring: if (col->linkedSizeName) { + struct asColumn *linkedSize = col->linkedSize; fprintf(f, " int arraySize;\n"); fprintf(f, " sql%sDynamicArray(val, &el->%s, &arraySize);\n", lt->listyName, col->name); - fprintf(f, " raToStructArraySizer(lf, arraySize, &el->%s, \"%s\");\n", - col->linkedSize->name, col->name); + fprintf(f, " raToStructArray%sSizer(lf, arraySize, &el->%s, \"%s\");\n", + linkedSize->lowType->listyName, linkedSize->name, col->name); } else if (col->fixedSize) fprintf(f, " sql%sArray(val, el->%s, %d);\n", lt->listyName, col->name, col->fixedSize); else internalErr(); break; default: errAbort("Sorry, %s array column is too complex for this program", col->name); break; } } else { /* Case of scalar (not array) variable. */ switch (type) { /* Handle numerical types */ case t_float: case t_double: case t_int: case t_uint: case t_short: case t_ushort: case t_off: + if (col->isSizeLink) + { + fprintf(f, " %s arraySize = sql%s(val);\n", + lt->cName, lt->nummyName); + fprintf(f, " raToStructArray%sSizer(lf, arraySize, &el->%s, \"%s\");\n", + lt->listyName, col->name, col->name); + } + else fprintf(f, " el->%s = sql%s(val);\n", col->name, lt->nummyName); break; /* Handle string types */ case t_string: case t_lstring: fprintf(f, " el->%s = cloneString(val);\n", col->name); break; /* Abort on other types */ default: errAbort("Sorry, %s column is too complex for this program", col->name); break; } } fprintf(f, " break;\n"); fprintf(f, " }\n"); @@ -403,18 +417,19 @@ 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"); +extraH = optionVal("extraH", extraH); raToStructGen(argv[1], argv[2]); return 0; }