be4311c07e14feb728abc6425ee606ffaa611a58 markd Fri Jan 22 06:46:58 2021 -0800 merge with master diff --git src/lib/fieldedTable.c src/lib/fieldedTable.c index 0742669..79a4658 100644 --- src/lib/fieldedTable.c +++ src/lib/fieldedTable.c @@ -178,86 +178,96 @@ if (doReverse) slReverse(&pairList); /* Convert rowList to have same order. */ struct fieldedRow *newList = NULL; for (pair = pairList; pair != NULL; pair = pair->next) { fr = pair->val; slAddHead(&newList, fr); } slReverse(&newList); table->rowList = newList; lmCleanup(&lm); } -struct fieldedTable *fieldedTableFromTabFile(char *fileName, char *reportFileName, +struct fieldedTable *fieldedTableReadTabHeader(struct lineFile *lf, char *requiredFields[], int requiredCount) -/* Read table from tab-separated file with a #header line that defines the fields. Ensures - * all requiredFields (if any) are present. The reportFileName is just used for error reporting and - * should be NULL for most purposes. This is used by edwSubmit though which - * first copies to a local file, and we want to report errors from the remote file. - * We do know the remote file exists at least, because we just copied it. */ -{ -/* Open file with fileName */ -struct lineFile *lf = netLineFileOpen(fileName); - -/* Substitute in reportFileName for error reporting */ -if (reportFileName != NULL) - { - if (differentString(reportFileName, fileName)) - { - freeMem(lf->fileName); - lf->fileName = cloneString(reportFileName); - } - } -else +/* Read in first line of file treating it as a fieldedTable header line. + * Used in combination with fieldedTableReadNextRow() */ { - reportFileName = fileName; - } - /* Get first line and turn it into field list. */ char *line; if (!lineFileNext(lf, &line, NULL)) - errAbort("%s is empty", reportFileName); + errAbort("%s is empty", lf->fileName); boolean startsSharp = FALSE; if (line[0] == '#') { line = skipLeadingSpaces(line+1); startsSharp = TRUE; } int fieldCount = chopByChar(line, '\t', NULL, 0); char *fields[fieldCount]; chopTabs(line, fields); /* Make sure that all required fields are present. */ int i; for (i = 0; i < requiredCount; ++i) { char *required = requiredFields[i]; int ix = stringArrayIx(required, fields, fieldCount); if (ix < 0) - errAbort("%s is missing required field '%s'", reportFileName, required); + errAbort("%s is missing required field '%s'", lf->fileName, required); } /* Create fieldedTable . */ -struct fieldedTable *table = fieldedTableNew(reportFileName, fields, fieldCount); +struct fieldedTable *table = fieldedTableNew(lf->fileName, fields, fieldCount); table->startsSharp = startsSharp; -while (lineFileRowTab(lf, fields)) +return table; +} + +struct fieldedTable *fieldedTableFromTabFile(char *fileName, char *reportFileName, + char *requiredFields[], int requiredCount) +/* Read table from tab-separated file with a #header line that defines the fields. Ensures + * all requiredFields (if any) are present. The reportFileName is just used for error reporting and + * should be NULL for most purposes. This is used by edwSubmit though which + * first copies to a local file, and we want to report errors from the remote file. + * We do know the remote file exists at least, because we just copied it. */ +{ +/* Open file with fileName */ +struct lineFile *lf = netLineFileOpen(fileName); + +/* Substitute in reportFileName for error reporting */ +if (reportFileName != NULL) + { + if (differentString(reportFileName, fileName)) + { + freeMem(lf->fileName); + lf->fileName = cloneString(reportFileName); + } + } +else + { + reportFileName = fileName; + } + +struct fieldedTable *table = fieldedTableReadTabHeader(lf, requiredFields, requiredCount); +char *row[table->fieldCount]; +while (lineFileNextRowTab(lf, row, table->fieldCount)) { - fieldedTableAdd(table, fields, fieldCount, lf->lineIx); + fieldedTableAdd(table, row, table->fieldCount, lf->lineIx); } /* Clean up and go home. */ lineFileClose(&lf); return table; } void fieldedTableToTabFileWithId(struct fieldedTable *table, char *fileName, char *idField, int startId) /* Write out a fielded table back to file. If idField is non-NULL it will be added * to the start of each output line as a steadily incrementing integer starting with startId. */ { FILE *f = mustOpen(fileName, "w"); /* Write out header row with optional leading # */