char *userRegionsParse(char *db, char *regionsText, int maxRegions, int maxErrs, int *retRegionCount, char **retWarnText) /* Parse user regions entered as BED3, BED4 or chr:start-end optionally followed by name. * Return name of trash file containing BED for parsed regions if regionsText contains * valid regions; otherwise NULL. * If maxRegions <= 0, it is ignored; likewise for maxErrs. * If retRegionCount is non-NULL, it will be set to the number of valid parsed regions * in the trash file. * If retWarnText is non-NULL, it will be set to a string containing warning and error * messages encountered while parsing input. */ { char *trashFileName = NULL; if (isNotEmpty(regionsText)) { char *copy = cloneString(regionsText); struct dyString *dyWarn = dyStringNew(0); struct bed4 *bedList = parseRegionInput(db, copy, maxRegions, maxErrs, dyWarn); if (retWarnText != NULL) { if (dyWarn->stringSize > 0) *retWarnText = dyStringCannibalize(&dyWarn); else { *retWarnText = NULL; dyStringFree(&dyWarn); } } int regionCount = slCount(bedList); if (retRegionCount != NULL) *retRegionCount = regionCount; if (regionCount > 0) { struct tempName tn; trashDirFile(&tn, "hgtData", "user", ".region"); trashFileName = cloneString(tn.forCgi); FILE *f = mustOpen(trashFileName, "w"); struct bed4 *bed; for (bed = bedList; bed; bed = bed->next ) { char *name = bed->name ? bed->name : ""; fprintf(f, "%s\t%d\t%d\t%s\n", bed->chrom, bed->chromStart, bed->chromEnd, name); } carefulClose(&f); } freeMem(copy); } else { if (retRegionCount != NULL) *retRegionCount = 0; if (retWarnText != NULL) *retWarnText = NULL; } return trashFileName; }
void doSubmitUserRegions(struct sqlConnection *conn) /* Process submit in set regions page. */ { char *idText = trimSpaces(cartString(cart, hgtaEnteredUserRegions)); char *userRegionFile = trimSpaces(cartString(cart, hgtaEnteredUserRegionFile)); boolean hasData = (idText != NULL && idText[0] != 0) || (userRegionFile != NULL && userRegionFile[0] != 0); /* beware, the string pointers from cartString() point to strings in the * cart hash. If they are manipulated and changed, they will get saved * back to the cart in their changed form. You don't want to be * altering them like that. Thus, the idText is duplicated below with * the cloneString(idText) */ htmlOpen("Table Browser (Region definitions)"); /* presence of fileName text overrides previously existing text area * contents */ if (userRegionFile != NULL && userRegionFile[0] != 0) { idText = cloneString(userRegionFile); cartRemove(cart, hgtaEnteredUserRegions); cartRemove(cart, hgtaUserRegionsFile); cartSetString(cart, hgtaEnteredUserRegions, idText); } else idText = cloneString(idText); char *lineLimitText = limitText(idText); if ( (strlen(lineLimitText) > 0) && (strlen(lineLimitText) != strlen(idText)) ) { freeMem(idText); idText = lineLimitText; cartSetString(cart, hgtaEnteredUserRegions, lineLimitText); } else freeMem(lineLimitText); if (hasData) { struct tempName tn; FILE *f; struct bed *bedEl; struct bed *bedList = parseRegionInput(idText); if (NULL == bedList) errAbort("no valid data points found in input"); trashDirFile(&tn, "hgtData", "user", ".region"); f = mustOpen(tn.forCgi, "w"); for (bedEl = bedList; bedEl; bedEl = bedEl->next ) { if (bedEl->name) fprintf(f, "%s\t%d\t%d\t%s\n", bedEl->chrom, bedEl->chromStart, bedEl->chromEnd, bedEl->name); else fprintf(f, "%s\t%d\t%d\n", bedEl->chrom, bedEl->chromStart, bedEl->chromEnd); } carefulClose(&f); cartSetString(cart, hgtaUserRegionsDb, database); cartSetString(cart, hgtaUserRegionsTable, curTable); cartSetString(cart, hgtaUserRegionsFile, tn.forCgi); cartSetString(cart, hgtaRegionType, hgtaRegionTypeUserRegions); if (strlen(idText) > 64 * 1024) cartRemove(cart, hgtaEnteredUserRegions); } else { cartRemove(cart, hgtaUserRegionsFile); cartRemove(cart, hgtaEnteredUserRegionFile); cartRemove(cart, hgtaRegionType); } mainPageAfterOpen(conn); htmlClose(); }