struct qaSeq *qacReadNext(FILE *f, boolean isSwapped) /* Read in next record in .qac file. */ { bits32 cSize, origSize; struct qaSeq *qa; signed char *buf; char *s; s = readString(f); if (s == NULL) return NULL; AllocVar(qa); qa->name = s; mustReadOne(f, origSize); if (isSwapped) origSize = byteSwap32(origSize); mustReadOne(f, cSize); if (isSwapped) cSize = byteSwap32(cSize); qa->size = origSize; qa->qa = needLargeMem(origSize); buf = needLargeMem(cSize); mustRead(f, buf, cSize); rleUncompress(buf, cSize, qa->qa, origSize); freeMem(buf); return qa; }
struct hash *qacReadToHash(char *fileName) /* Read in a qac file into a hash of qacs keyed by name. */ { boolean isSwapped; FILE *f = qacOpenVerify(fileName, &isSwapped); bits32 compSize, uncSize; struct qac *qac; char *name; struct hash *hash = newHash(18); int count = 0; for (;;) { name = readString(f); if (name == NULL) break; mustReadOne(f, uncSize); if (isSwapped) uncSize = byteSwap32(uncSize); mustReadOne(f, compSize); if (isSwapped) compSize = byteSwap32(compSize); qac = needHugeMem(sizeof(*qac) + compSize - 1); qac->uncSize = uncSize; qac->compSize = compSize; mustRead(f, qac->data, compSize); hashAdd(hash, name, qac); ++count; } carefulClose(&f); printf("Read %d qacs from %s\n", count, fileName); return hash; }
struct i16Header *i16ReadHeaderOnly(char *input) /* Just read header, not rest. */ { FILE *f = mustOpen(input, "r"); struct i16Header *header; AllocVar(header); mustRead(f, header, sizeof(*header)); carefulClose(&f); return header; }
struct gdfGene *gdfReadOneGene(FILE *f) /* Read one entry from a Gdf file. Assumes that the file pointer * is in the right place. */ { short pointCount; char strand; UBYTE geneNameSize, chromIx; char geneNameBuf[128]; struct gdfGene *gene; mustReadOne(f, geneNameSize); mustRead(f, geneNameBuf, geneNameSize); geneNameBuf[geneNameSize] = 0; mustReadOne(f, chromIx); mustReadOne(f, strand); mustReadOne(f, pointCount); gene = newGdfGene(geneNameBuf, geneNameSize, pointCount>>1, strand, chromIx); mustRead(f, gene->dataPoints, sizeof(gene->dataPoints[0]) * pointCount); return gene; }
void readInGulp(char *fileName, char **retBuf, size_t *retSize) /* Read whole file in one big gulp. */ { size_t size = (size_t)fileSize(fileName); char *buf; FILE *f = mustOpen(fileName, "rb"); *retBuf = buf = needLargeMem(size+1); mustRead(f, buf, size); buf[size] = 0; /* Just in case it needs zero termination. */ fclose(f); if (retSize != NULL) *retSize = size; }
void rangeReadArray(FILE *f, struct rangeStartSize *r, int n, boolean isSwapped) /* Read 'n' elements of range array (start,size) from file 'f'. */ { mustRead(f, r, n*sizeof(*r)); if (isSwapped) { while (n) { r->start = byteSwap32(r->start); r->size = byteSwap32(r->size); --n; ++r; } } }
void mapReadString(FILE *f, char **ps) /* Read string from map file. */ { short len; char *s; mustReadOne(f, len); if (len == 0) s = NULL; else { s = needMem(len+1); mustRead(f, s, len); } *ps = s; }
struct nt4Seq *loadNt4(char *fileName, char *seqName) /* Load up an nt4 sequence from a file. */ { bits32 size; struct nt4Seq *seq; FILE *f = nt4OpenVerify(fileName); mustReadOne(f, size); if (seqName == NULL) seqName = fileName; seq = allocNt4(size, seqName); mustRead(f, seq->bases, bits32PaddedSize(size)); carefulClose(&f); return seq; }
void copyFileBytes(FILE *in, FILE *out, bits64 size) /* Copy bytes to a file. */ { char buf[4*1024]; bits64 sizeLeft = size; bits64 oneSize; while (sizeLeft > 0) { oneSize = sizeLeft; if (oneSize > sizeof(buf)) oneSize = sizeof(buf); mustRead(in, buf, oneSize); mustWrite(out, buf, oneSize); sizeLeft -= oneSize; } }
char *cartDbMakeRandomKey(int numBits) /* Generate base64 encoding of a random key of at least size numBits returning string to be freed when done */ { int numBytes = (numBits + 7) / 8; // round up to nearest whole byte. numBytes = ((numBytes+2)/3)*3; // round up to the nearest multiple of 3 to avoid equals-char padding in base64 output FILE *f = mustOpen("/dev/urandom", "r"); // open random system device for read-only access. char *binaryString = needMem(numBytes); mustRead(f, binaryString, numBytes); carefulClose(&f); char * result = base64Encode(binaryString, numBytes); // converts 3 binary bytes into 4 printable characters int len = strlen(result); memSwapChar(result, len, '+', 'A'); // replace + and / with characters that are URL-friendly. memSwapChar(result, len, '/', 'a'); freeMem(binaryString); return result; }
static struct wormFeature *scanChromOffsetFile(char *dir, char *suffix, bits32 signature, int nameOffset, char *chromId, int start, int end, int addEnd) /* Scan a chrom.pgo or chrom.cdo file for names of things that are within * range. */ { FILE *f; char fileName[512]; bits32 sig, nameSize, entryCount; int entrySize; int *entry; char *name; bits32 i; struct wormFeature *list = NULL, *el; char *typePt; char typeByte; sprintf(fileName, "%s%s%s", dir, chromId, suffix); f = mustOpen(fileName, "rb"); mustReadOne(f, sig); if (sig != signature) errAbort("Bad signature on %s", fileName); mustReadOne(f, entryCount); mustReadOne(f, nameSize); entrySize = nameSize + nameOffset; entry = needMem(entrySize + 1); name = (char *)entry; name += nameOffset; typePt = name-1; for (i=0; i<entryCount; ++i) { mustRead(f, entry, entrySize); if (entry[0] > end) break; if (entry[1] < start) continue; typeByte = *typePt; el = newWormFeature(name, chromId, entry[0], entry[1]+addEnd, typeByte); slAddHead(&list, el); } slReverse(&list); fclose(f); freeMem(entry); return list; }
static void checkExtRecord(struct seqFields *seq, char *extPath) /* Check the external file record for a sequence (slow). Assumes * that bounds have been sanity check for a file. */ { /* read range into buffer */ FILE *fh = mustOpen(extPath, "r"); char *faBuf; char accVer[GB_ACC_BUFSZ]; struct dnaSeq *dnaSeq; if (fseeko(fh, seq->file_offset, SEEK_SET) < 0) { gbError("%s: can't seek %s", seq->acc, extPath); carefulClose(&fh); } faBuf = needMem(seq->file_size+1); mustRead(fh, faBuf, seq->file_size); faBuf[seq->file_size] = '\0'; carefulClose(&fh); /* verify contents */ if (faBuf[0] != '>') { gbError("%s: gbExtFile offset %lld doesn't start a fasta record: %s", seq->acc, (long long)seq->file_offset, extPath); free(faBuf); return; } dnaSeq = faFromMemText(faBuf); safef(accVer, sizeof(accVer), "%s.%d", seq->acc, seq->version); if (!sameString(dnaSeq->name, accVer)) gbError("%s: name in fasta header \"%s\" doesn't match expected \"%s\": %s", seq->acc, dnaSeq->name, accVer, extPath); if (dnaSeq->size != seq->size) gbError("%s: size of fasta sequence (%d) doesn't match expected (%d): %s", seq->acc, dnaSeq->size, seq->size, extPath); freeDnaSeq(&dnaSeq); }
void _pf_cm_file_readShort(_pf_Stack *stack) /* Read a Short from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Short, sizeof(stack[0].Short)); }
void _pf_cm_file_readByte(_pf_Stack *stack) /* Read a Byte from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Byte, sizeof(stack[0].Byte)); }
static void itsaWriteMerged(struct chromInfo *chromList, DNA *allDna, bits32 *offsetArray, bits32 *listArray, bits32 *index13, char *output) /* Write out a file that contains a single splix that is the merger of * all of the individual splixes in list. As a side effect will replace * offsetArray with suffix array and listArray with traverse array */ { FILE *f = mustOpen(output, "w+"); /** Allocate header and fill out easy constant fields. */ struct itsaFileHeader *header; AllocVar(header); header->majorVersion = ITSA_MAJOR_VERSION; header->minorVersion = ITSA_MINOR_VERSION; /* Figure out sizes of names and sequence for each chromosome. */ struct chromInfo *chrom; bits32 chromNamesSize = 0; bits64 dnaDiskSize = 1; /* For initial zero. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) { chromNamesSize += strlen(chrom->name) + 1; dnaDiskSize += chrom->size + 1; /* Include separating zeroes. */ } /* Fill in most of rest of header fields */ header->chromCount = slCount(chromList); header->chromNamesSize = roundUpTo4(chromNamesSize); header->dnaDiskSize = roundUpTo4(dnaDiskSize); bits32 chromSizesSize = header->chromCount*sizeof(bits32); /* Write header. */ mustWrite(f, header, sizeof(*header)); /* Write chromosome names. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) mustWrite(f, chrom->name, strlen(chrom->name)+1); zeroPad(f, header->chromNamesSize - chromNamesSize); /* Write chromosome sizes. */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) mustWrite(f, &chrom->size, sizeof(chrom->size)); int chromSizesSizePad = chromSizesSize - header->chromCount * sizeof(bits32); zeroPad(f, chromSizesSizePad); /* Write out chromosome DNA and zeros before, between, and after. */ mustWrite(f, allDna, dnaDiskSize); zeroPad(f, header->dnaDiskSize - dnaDiskSize); verboseTime(1, "Wrote %lld bases of DNA including zero padding", header->dnaDiskSize); /* Calculate and write suffix array. Convert index13 to index of array as opposed to index * of sequence. */ bits64 arraySize = 0; off_t suffixArrayFileOffset = ftello(f); int slotCount = itsaSlotCount; int slotIx; for (slotIx=0; slotIx < slotCount; ++slotIx) { int slotSize = finishAndWriteOneSlot(offsetArray, listArray, index13[slotIx], allDna, f); /* Convert index13 to hold the position in the suffix array where the first thing matching * the corresponding 13-base prefix is found. */ if (slotSize != 0) index13[slotIx] = arraySize+1; /* The +1 is so we can keep 0 for not found. */ else index13[slotIx] = 0; arraySize += slotSize; if ((slotIx % 200000 == 0) && slotIx != 0) { verboseDot(); if (slotIx % 10000000 == 0) verbose(1, "fine sort bucket %d of %d\n", slotIx, slotCount); } } verbose(1, "fine sort bucket %d of %d\n", slotCount, slotCount); verboseTime(1, "Wrote %lld suffix array positions", arraySize); /* Now we're done with the offsetArray and listArray buffers, so use them for the * next phase. */ bits32 *suffixArray = offsetArray; offsetArray = NULL; /* Help make some errors more obvious */ bits32 *traverseArray = listArray; listArray = NULL; /* Help make some errors more obvious */ /* Read the suffix array back from the file. */ fseeko(f, suffixArrayFileOffset, SEEK_SET); mustRead(f, suffixArray, arraySize*sizeof(bits32)); verboseTime(1, "Read suffix array back in"); /* Calculate traverse array and cursor arrays */ memset(traverseArray, 0, arraySize*sizeof(bits32)); UBYTE *cursorArray = needHugeMem(arraySize); itsaFillInTraverseArray(allDna, suffixArray, arraySize, traverseArray, cursorArray); verboseTime(1, "Filled in traverseArray"); /* Write out traverse array. */ mustWrite(f, traverseArray, arraySize*sizeof(bits32)); verboseTime(1, "Wrote out traverseArray"); /* Write out 13-mer index. */ mustWrite(f, index13, itsaSlotCount*sizeof(bits32)); verboseTime(1, "Wrote out index13"); /* Write out bits of cursor array corresponding to index. */ for (slotIx=0; slotIx<itsaSlotCount; ++slotIx) { bits32 indexPos = index13[slotIx]; if (indexPos == 0) fputc(0, f); else fputc(cursorArray[indexPos-1], f); } verboseTime(1, "Wrote out cursors13"); /* Update a few fields in header, and go back and write it out again with * the correct magic number to indicate it's complete. */ header->magic = ITSA_MAGIC; header->arraySize = arraySize; header->size = sizeof(*header) // header + header->chromNamesSize + // chromosome names + header->chromCount * sizeof(bits32) // chromosome sizes + header->dnaDiskSize // dna sequence + sizeof(bits32) * arraySize // suffix array + sizeof(bits32) * arraySize // traverse array + sizeof(bits32) * itsaSlotCount // index13 + sizeof(UBYTE) * itsaSlotCount; // cursors13 rewind(f); mustWrite(f, header, sizeof(*header)); carefulClose(&f); verbose(1, "Completed %s is %lld bytes\n", output, header->size); }
char *menuBar(struct cart *cart, char *db) // Return HTML for the menu bar (read from a configuration file); // we fixup internal CGI's to add hgsid's and include the appropriate js and css files. // // Note this function is also called by hgTracks which extends the menu bar // with a View menu defined in hgTracks/menu.c { char *docRoot = hDocumentRoot(); char *menuStr, buf[4096], uiVars[128]; FILE *fd; char *navBarFile = "inc/globalNavBar.inc"; struct stat statBuf; char *scriptName = cgiScriptName(); if (cart) safef(uiVars, sizeof(uiVars), "%s=%s", cartSessionVarName(), cartSessionId(cart)); else uiVars[0] = 0; if(docRoot == NULL) // tolerate missing docRoot (i.e. don't bother with menu when running from command line) return NULL; jsIncludeFile("jquery.js", NULL); jsIncludeFile("jquery.plugins.js", NULL); webIncludeResourceFile("nice_menu.css"); // Read in menu bar html safef(buf, sizeof(buf), "%s/%s", docRoot, navBarFile); fd = mustOpen(buf, "r"); fstat(fileno(fd), &statBuf); int len = statBuf.st_size; menuStr = needMem(len + 1); mustRead(fd, menuStr, statBuf.st_size); menuStr[len] = 0; carefulClose(&fd); if (cart) { char *newMenuStr = menuBarAddUiVars(menuStr, "/cgi-bin/hg", uiVars); freez(&menuStr); menuStr = newMenuStr; } if(scriptName) { // Provide hgTables options for some CGIs. char hgTablesOptions[1024] = ""; char *track = (cart == NULL ? NULL : (endsWith(scriptName, "hgGene") ? cartOptionalString(cart, "hgg_type") : cartOptionalString(cart, "g"))); if (track && cart && db && (endsWith(scriptName, "hgc") || endsWith(scriptName, "hgTrackUi") || endsWith(scriptName, "hgGene"))) { struct trackDb *tdb = hTrackDbForTrack(db, track); if (tdb) { struct trackDb *topLevel = trackDbTopLevelSelfOrParent(tdb); safef(hgTablesOptions, sizeof hgTablesOptions, "../cgi-bin/hgTables?hgta_doMainPage=1&hgta_group=%s&hgta_track=%s&hgta_table=%s&", topLevel->grp, topLevel->track, tdb->table); menuStr = replaceChars(menuStr, "../cgi-bin/hgTables?", hgTablesOptions); trackDbFree(&tdb); } } } if(!loginSystemEnabled()) stripRegEx(menuStr, "<\\!-- LOGIN_START -->.*<\\!-- LOGIN_END -->", REG_ICASE); if(scriptName) { // Provide optional official mirror servers menu items char *geoMenu = geoMirrorMenu(); char *pattern = "<!-- OPTIONAL_MIRROR_MENU -->"; char *newMenuStr = replaceChars(menuStr, pattern, geoMenu); freez(&menuStr); menuStr = newMenuStr; } if(scriptName) { // Provide view menu for some CGIs. struct dyString *viewItems = dyStringCreate(""); boolean hasViewMenu = TRUE; if (endsWith(scriptName, "hgGenome")) { safef(buf, sizeof(buf), "../cgi-bin/hgGenome?%s&hgGenome_doPsOutput=1", uiVars); dyStringPrintf(viewItems, "<li><a href='%s' id='%s'>%s</a></li>\n", buf, "pdfLink", "PDF/PS"); } else { hasViewMenu = FALSE; } if (hasViewMenu) { struct dyString *viewMenu = dyStringCreate("<li class='menuparent' id='view'><span>View</span>\n<ul style='display: none; visibility: hidden;'>\n"); dyStringAppend(viewMenu, viewItems->string); dyStringAppend(viewMenu, "</ul>\n</li>\n"); menuStr = replaceChars(menuStr, "<!-- OPTIONAL_VIEW_MENU -->", viewMenu->string); dyStringFree(&viewMenu); } else if (!endsWith(scriptName, "hgTracks")) { replaceChars(menuStr, "<!-- OPTIONAL_VIEW_MENU -->", ""); } dyStringFree(&viewItems); } if(scriptName) { // Provide context sensitive help links for some CGIs. char *link = NULL; char *label = NULL; if (endsWith(scriptName, "hgBlat")) { link = "../goldenPath/help/hgTracksHelp.html#BLATAlign"; label = "Help on Blat"; } else if (endsWith(scriptName, "hgHubConnect")) { link = "../goldenPath/help/hgTrackHubHelp.html"; label = "Help on Track Hubs"; } else if (endsWith(scriptName, "hgNear")) { link = "../goldenPath/help/hgNearHelp.html"; label = "Help on Gene Sorter"; } else if (endsWith(scriptName, "hgTables")) { link = "../goldenPath/help/hgTablesHelp.html"; label = "Help on Table Browser"; } else if (endsWith(scriptName, "hgGenome")) { link = "../goldenPath/help/hgGenomeHelp.html"; label = "Help on Genome Graphs"; } else if (endsWith(scriptName, "hgSession")) { link = "../goldenPath/help/hgSessionHelp.html"; label = "Help on Sessions"; } else if (endsWith(scriptName, "hgVisiGene")) { link = "../goldenPath/help/hgTracksHelp.html#VisiGeneHelp"; label = "Help on VisiGene"; } else if (endsWith(scriptName, "hgCustom")) { link = "../goldenPath/help/customTrack.html"; label = "Help on Custom Tracks"; } // Don't overwrite any previously set defaults if(!contextSpecificHelpLink && link) contextSpecificHelpLink = link; if(!contextSpecificHelpLabel && label) contextSpecificHelpLabel = label; } if(contextSpecificHelpLink) { char buf[1024]; safef(buf, sizeof(buf), "<li><a href='%s'>%s</a></li>", contextSpecificHelpLink, contextSpecificHelpLabel); menuStr = replaceChars(menuStr, "<!-- CONTEXT_SPECIFIC_HELP -->", buf); } return menuStr; }
void _pf_cm_file_readFloat(_pf_Stack *stack) /* Read a Float from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Float, sizeof(stack[0].Float)); }
void _pf_cm_file_readInt(_pf_Stack *stack) /* Read a Int from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Int, sizeof(stack[0].Int)); }
static bool readNextBlock(BinaryFileReaderData * data, char ** lastChrom, int * lastStart, bool * pointByPoint) { BlockData * block = calloc(1, sizeof(BlockData)); char ** chromPtr = block->chroms; int * startPtr = block->starts; int * finishPtr = block->finishes; double * valuePtr = block->values; char c; bool startSet = true; int32_t holder; float holder2; for (block->count = 0; block->count < BLOCK_LENGTH; block->count++) { // Check whether file finished if (fread(&c, 1, 1, data->file) == 0) { appendNewBlock(data, block); // Increment counter to push the reader into NULL block pthread_mutex_lock(&data->count_mutex); data->count++; pthread_mutex_unlock(&data->count_mutex); return true; } if (*pointByPoint) startSet = false; // Read header if (c == 1) { // Point by Point *pointByPoint = true; mustRead(&c, 1, 1, data->file); if (c) { *chromPtr = calloc(1000, 1); char * ptr = * chromPtr; int pos; for (pos = 0; pos < 1000 && c; pos++) { *ptr = c; mustRead(&c, 1, 1, data->file); ptr++; } while (c) mustRead(&c, 1, 1, data->file); } mustRead(&holder, sizeof(int32_t), 1, data->file); *startPtr = holder; startSet = true; } else if (c == 2) { // Normal *pointByPoint = false; mustRead(&c, 1, 1, data->file); if (c) { *chromPtr = calloc(1000, 1); char * ptr = * chromPtr; int pos; for (pos = 0; pos < 1000 && c; pos++) { *ptr = c; mustRead(&c, 1, 1, data->file); ptr++; } while (c) mustRead(&c, 1, 1, data->file); } } // Set chromosome if unset in header if (*chromPtr == NULL) *chromPtr = *lastChrom; // Read coords if (*pointByPoint) { if (!startSet) *startPtr = *lastStart + 1; *finishPtr = *startPtr + 1; } else { mustRead(&holder, sizeof(int32_t), 1, data->file); *startPtr = holder; mustRead(&holder, sizeof(int32_t), 1, data->file); *finishPtr = holder; } // Read value mustRead(&holder2, sizeof(float), 1, data->file); *valuePtr = holder2; // Record stuff *lastChrom = *chromPtr; *lastStart = *startPtr; // Step ahead chromPtr++; startPtr++; finishPtr++; valuePtr++; } return appendNewBlock(data, block); }
void _pf_cm_file_readLong(_pf_Stack *stack) /* Read a Long from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Long, sizeof(stack[0].Long)); }
struct xaAli *xaReadNext(FILE *f, boolean condensed) /* Read next xaAli from file. If condensed * don't fill int query, target, qSym, tSym, or hSym. */ { char line[512]; char *words[16]; int wordCount; struct xaAli *xa; char *parts[5]; int partCount; double percentScore; int symCount; int newOffset = 0; char *s, *e; /* Get first line and parse out everything but the sym lines. */ if (fgets(line, sizeof(line), f) == NULL) return NULL; wordCount = chopLine(line, words); if (wordCount < 9) errAbort("Short line in cross-species alignment file"); if (wordCount == 10) newOffset = 1; if (!sameString(words[1], "align")) errAbort("Bad line in cross-species alignment file"); AllocVar(xa); xa->name = cloneString(words[0]); s = words[5+newOffset]; e = strrchr(s, ':'); if (e == NULL) errAbort("Bad line (no colon) in cross-species alignment file"); *e++ = 0; partCount = chopString(e, "-", parts, ArraySize(parts)); if (partCount != 2) errAbort("Bad range format in cross-species alignment file"); if (!condensed) xa->query = cloneString(s); xa->qStart = atoi(parts[0]); xa->qEnd = atoi(parts[1]); xa->qStrand = words[6+newOffset][0]; partCount = chopString(words[7+newOffset], ":-", parts, ArraySize(parts)); if (!condensed) xa->target = cloneString(parts[0]); xa->tStart = atoi(parts[1]); xa->tEnd = atoi(parts[2]); xa->tStrand = words[8+newOffset][0]; percentScore = atof(words[2]); xa->milliScore = round(percentScore*10); xa->symCount = symCount = atoi(words[4]); /* Get symbol lines. */ if (condensed) { eatThroughLf(f); eatThroughLf(f); eatThroughLf(f); } else { xa->qSym = needMem(symCount+1); mustRead(f, xa->qSym, symCount); eatLf(f); xa->tSym = needMem(symCount+1); mustRead(f, xa->tSym, symCount); eatLf(f); xa->hSym = needMem(symCount+1); mustRead(f, xa->hSym, symCount); eatLf(f); } return xa; }
void _pf_cm_file_readDouble(_pf_Stack *stack) /* Read a Double from file. */ { struct file *file = stack[0].v; mustRead(file->f, &stack[0].Double, sizeof(stack[0].Double)); }
char *menuBar(struct cart *cart) // Return HTML for the menu bar (read from a configuration file); // we fixup internal CGI's to add hgsid's and include the appropriate js and css files. { char *docRoot = hDocumentRoot(); char *menuStr, buf[4096], uiVars[128]; FILE *fd; int len, offset, err; char *navBarFile = "inc/globalNavBar.inc"; struct stat statBuf; regex_t re; regmatch_t match[2]; char *scriptName = cgiScriptName(); if (cart) safef(uiVars, sizeof(uiVars), "%s=%u", cartSessionVarName(), cartSessionId(cart)); else uiVars[0] = 0; if(docRoot == NULL) // tolerate missing docRoot (i.e. don't bother with menu when running from command line) return NULL; jsIncludeFile("jquery.js", NULL); jsIncludeFile("jquery.plugins.js", NULL); webIncludeResourceFile("nice_menu.css"); // Read in menu bar html safef(buf, sizeof(buf), "%s/%s", docRoot, navBarFile); fd = mustOpen(buf, "r"); fstat(fileno(fd), &statBuf); len = statBuf.st_size; menuStr = needMem(len + 1); mustRead(fd, menuStr, statBuf.st_size); menuStr[len] = 0; carefulClose(&fd); if (cart) { // fixup internal CGIs to have hgsid safef(buf, sizeof(buf), "/cgi-bin/hg[A-Za-z]+(%c%c?)", '\\', '?'); err = regcomp(&re, buf, REG_EXTENDED); if(err) errAbort("regcomp failed; err: %d", err); struct dyString *dy = newDyString(0); for(offset = 0; offset < len && !regexec(&re, menuStr + offset, ArraySize(match), match, 0); offset += match[0].rm_eo) { dyStringAppendN(dy, menuStr + offset, match[0].rm_eo); if(match[1].rm_so == match[1].rm_eo) dyStringAppend(dy, "?"); dyStringAppend(dy, uiVars); if(match[1].rm_so != match[1].rm_eo) dyStringAppend(dy, "&"); } if(offset < len) dyStringAppend(dy, menuStr + offset); freez(&menuStr); menuStr = dyStringCannibalize(&dy); } if(!loginSystemEnabled()) stripRegEx(menuStr, "<\\!-- LOGIN_START -->.*<\\!-- LOGIN_END -->", REG_ICASE); if(scriptName) { // Provide optional official mirror servers menu items char *geoMenu = geoMirrorMenu(); char *pattern = "<!-- OPTIONAL_MIRROR_MENU -->"; char *newMenuStr = replaceChars(menuStr, pattern, geoMenu); freez(&menuStr); menuStr = newMenuStr; } if(scriptName) { // Provide view menu for some CGIs. struct dyString *viewItems = dyStringCreate(""); boolean hasViewMenu = TRUE; if (endsWith(scriptName, "hgGenome")) { safef(buf, sizeof(buf), "../cgi-bin/hgGenome?%s&hgGenome_doPsOutput=1", uiVars); dyStringPrintf(viewItems, "<li><a href='%s' id='%s'>%s</a></li>\n", buf, "pdfLink", "PDF/PS"); } else { hasViewMenu = FALSE; } if (hasViewMenu) { struct dyString *viewMenu = dyStringCreate("<li class='menuparent' id='view'><span>View</span>\n<ul style='display: none; visibility: hidden;'>\n"); dyStringAppend(viewMenu, viewItems->string); dyStringAppend(viewMenu, "</ul>\n</li>\n"); menuStr = replaceChars(menuStr, "<!-- OPTIONAL_VIEW_MENU -->", viewMenu->string); dyStringFree(&viewMenu); } dyStringFree(&viewItems); } if(scriptName) { // Provide context sensitive help links for some CGIs. char *link = NULL; char *label = NULL; if (endsWith(scriptName, "hgBlat")) { link = "../goldenPath/help/hgTracksHelp.html#BLATAlign"; label = "Help on Blat"; } else if (endsWith(scriptName, "hgHubConnect")) { link = "../goldenPath/help/hgTrackHubHelp.html"; label = "Help on Track Hubs"; } else if (endsWith(scriptName, "hgNear")) { link = "../goldenPath/help/hgNearHelp.html"; label = "Help on Gene Sorter"; } else if (endsWith(scriptName, "hgTables")) { link = "../goldenPath/help/hgTablesHelp.html"; label = "Help on Table Browser"; } else if (endsWith(scriptName, "hgGenome")) { link = "../goldenPath/help/hgGenomeHelp.html"; label = "Help on Genome Graphs"; } else if (endsWith(scriptName, "hgSession")) { link = "../goldenPath/help/hgSessionHelp.html"; label = "Help on Sessions"; } else if (endsWith(scriptName, "hgVisiGene")) { link = "../goldenPath/help/hgTracksHelp.html#VisiGeneHelp"; label = "Help on VisiGene"; } else if (endsWith(scriptName, "hgCustom")) { link = "../goldenPath/help/customTrack.html"; label = "Help on Custom Tracks"; } // Don't overwrite any previously set defaults if(!contextSpecificHelpLink && link) contextSpecificHelpLink = link; if(!contextSpecificHelpLabel && label) contextSpecificHelpLabel = label; } if(contextSpecificHelpLink) { char buf[1024]; safef(buf, sizeof(buf), "<li><a href='%s'>%s</a></li>", contextSpecificHelpLink, contextSpecificHelpLabel); menuStr = replaceChars(menuStr, "<!-- CONTEXT_SPECIFIC_HELP -->", buf); } return menuStr; }