void xpParseEndTag(struct xp *xp, char *tagName) /* Call this after have seen </. It will parse through * > and make sure that the tagName matches. */ { struct dyString *dy = xp->endTag; char c; dyStringClear(dy); /* Skip leading space. */ for (;;) { if ((c = xpGetChar(xp)) == 0) xpUnexpectedEof(xp); if (isspace(c)) { if (c == '\n') ++xp->lineIx; } else break; } /* Read end tag. */ for (;;) { dyStringAppendC(dy, c); if ((c = xpGetChar(xp)) == 0) xpUnexpectedEof(xp); if (isspace(c)) { if (c == '\n') ++xp->lineIx; break; } if (c == '>') break; } /* Skip until '>' */ while (c != '>') { dyStringAppendC(dy, c); if ((c = xpGetChar(xp)) == 0) xpUnexpectedEof(xp); if (isspace(c)) { if (c == '\n') ++xp->lineIx; } else if (c != '>') xpError(xp, "Unexpected characters past first word in /%s tag", dy->string); } if (!sameString(dy->string, tagName)) xpError(xp, "Mismatch between start tag %s and end tag %s", tagName, dy->string); }
struct dnaSeq *faReadWithDash(FILE *f) /* Read in a fasta sequence that might include dashes. */ { int c; struct dnaSeq *seq; struct dyString *dy; char *line, *name; /* Get first > */ for (;;) { if ((c = fgetc(f)) == -1) return NULL; if (c == '>') break; } /* Get line into dy and then first word into name*/ dy = dyStringNew(0); for (;;) { if ((c = fgetc(f)) == -1) errAbort("Unexpected end of file"); if (c == '\n') break; dyStringAppendC(dy, c); } line = dy->string; name = cloneString(nextWord(&line)); /* Get up until next '>' into dy */ dyStringClear(dy); for (;;) { if ((c = fgetc(f)) == -1) break; if (isdigit(c) || isspace(c)) continue; if (c == '>') { ungetc(c, f); break; } dyStringAppendC(dy, c); } /* Create seq. */ AllocVar(seq); seq->name = name; seq->dna = cloneString(dy->string); seq->size = dy->stringSize; verbose(2, "seq %s, %d bases\n", seq->name, seq->size); dyStringFree(&dy); return seq; }
char *vcfGetSlashSepAllelesFromWords(char **words, struct dyString *dy, boolean *retSkippedFirstBase) /* Overwrite dy with a /-separated allele string from VCF words, * skipping the extra initial base that VCF requires for indel alleles if necessary. * Return dy->string for convenience. */ { dyStringClear(dy); // VCF reference allele gets its own column: char *refAllele = words[3]; char *altAlleles = words[4]; // First determine whether there is an extra initial base that we need to skip: boolean allStartSame = TRUE; char *p; while ((p = strchr(altAlleles, ',')) != NULL) { if (altAlleles[0] != refAllele[0]) allStartSame = FALSE; altAlleles = p+1; } if (altAlleles[0] != refAllele[0]) allStartSame = FALSE; int offset = allStartSame ? 1 : 0; if (refAllele[offset] == '\0') dyStringAppendC(dy, '-'); else dyStringAppend(dy, refAllele+offset); // VCF alternate alleles are comma-separated, make them /-separated: altAlleles = words[4]; if (isNotEmpty(altAlleles) && differentString(altAlleles, ".")) { // Now construct the string: while ((p = strchr(altAlleles, ',')) != NULL) { dyStringAppendC(dy, '/'); int len = p - altAlleles - offset; if (len == 0) dyStringAppendC(dy, '-'); else dyStringAppendN(dy, altAlleles+offset, len); altAlleles = p+1; } dyStringAppendC(dy, '/'); int len = strlen(altAlleles) - offset; if (len == 0) dyStringAppendC(dy, '-'); else dyStringAppendN(dy, altAlleles+offset, len); } if (retSkippedFirstBase) *retSkippedFirstBase = offset; return dy->string; }
void dyStringAppendEscapeQuotes(struct dyString *dy, char *string, char quot, char esc) /* Append escaped-for-quotation version of string to dy. */ { char c; char *s = string; while ((c = *s++) != 0) { if (c == quot) dyStringAppendC(dy, esc); dyStringAppendC(dy, c); } }
static void appendCgiVar(struct dyString *dy, char *name, char *value) /* Append cgiVar with cgi-encoded value to dy. */ { char *enc = NULL; if (value == NULL) value = ""; enc = cgiEncode(value); if (dy->stringSize != 0) dyStringAppendC(dy, '&'); dyStringAppend(dy, name); dyStringAppendC(dy, '='); dyStringAppend(dy, enc); freez(&enc); }
void dyStringQuoteString(struct dyString *dy, char quotChar, char *text) /* Append quotChar-quoted text (with any internal occurrences of quotChar * \-escaped) onto end of dy. */ { char c; dyStringAppendC(dy, quotChar); while ((c = *text++) != 0) { if (c == quotChar) dyStringAppendC(dy, '\\'); dyStringAppendC(dy, c); } dyStringAppendC(dy, quotChar); }
static void dyStringAppendQuoted(struct dyString *dy, char *s) /* Append s to dyString, surrounding with quotes and escaping * internal quotes. */ { char c; dyStringAppendC(dy, '"'); while ((c = *s++) != 0) { if (c == '"') dyStringAppendC(dy, '\\'); dyStringAppendC(dy, c); } dyStringAppendC(dy, '"'); dyStringAppendC(dy, ' '); }
static void visiSearcherWeedResults(struct visiSearcher *searcher, struct sqlConnection *conn) /* Get rid of images that are just partial matches, and also * images that are private. This leaks a little memory - the * matches that are weeded out.*/ { struct visiMatch *newList = NULL, *match, *next, key; int wordCount = searcher->wordCount; struct dyString *query = dyStringNew(0); struct sqlResult *sr; char **row; int passCount = 0; /* Construct query to fetch all non-private imageId's in matchList. */ dyStringAppend(query, "select image.id from image,submissionSet " "where submissionSet.privateUser = 0 " "and submissionSet.id = image.submissionSet " "and image.id in ("); for (match = searcher->matchList; match != NULL; match = next) { next = match->next; if (bitCountRange(match->wordBits, 0, wordCount) == wordCount) { if (passCount != 0) dyStringAppendC(query, ','); dyStringPrintf(query, "%d", match->imageId); ++passCount; } } dyStringAppendC(query, ')'); /* Execute query, and put corresponding images on newList. */ if (passCount > 0) { sr = sqlGetResult(conn, query->string); while ((row = sqlNextRow(sr)) != NULL) { key.imageId = sqlUnsigned(row[0]); match = rbTreeFind(searcher->tree, &key); if (match == NULL) internalErr(); slAddHead(&newList, match); } slReverse(&newList); } searcher->matchList = newList; dyStringFree(&query); }
static void makeOrderedCommaFieldList(struct slName *orderList, struct joinerDtf *dtfList, struct dyString *dy) /* Given list in order, and a subset of fields to use, make * a comma separated list of that subset in order. */ { struct joinerDtf *dtf; struct slName *order; boolean first = TRUE; struct hash *dtfHash = newHash(8); /* Build up hash of field names. */ for (dtf = dtfList; dtf != NULL; dtf = dtf->next) hashAdd(dtfHash, dtf->field, NULL); for (order = orderList; order != NULL; order = order->next) { if (hashLookup(dtfHash, order->name)) { if (first) first = FALSE; else dyStringAppendC(dy, ','); dyStringAppend(dy, order->name); } } hashFree(&dtfHash); }
static void parseSourceOrganism() /* parse source /organism fields, output as srcOrg if different from org */ { int numOrgs, i; char **orgs; if (gbSourceOrganism->val->stringSize == 0) return; if (srcOrgBuf == NULL) srcOrgBuf = dyStringNew(256); dyStringClear(srcOrgBuf); numOrgs = chopString(gbSourceOrganism->val->string, ";", NULL, 0); AllocArray(orgs, numOrgs); chopString(gbSourceOrganism->val->string, ";", orgs, numOrgs); for (i = 0; i < numOrgs; i++) { if (!sameString(orgs[i], gbOrganismField->val->string)) { if (srcOrgBuf->stringSize > 0) dyStringAppendC(srcOrgBuf, ';'); dyStringAppend(srcOrgBuf, orgs[i]); } } freeMem(orgs); if (srcOrgBuf->stringSize > 0) kvtAdd(kvt, "srcOrg", srcOrgBuf->string); }
static void errCatchWarnHandler(char *format, va_list args) /* Write an error to top of errCatchStack. */ { struct errCatch **pErrCatchStack = getStack(), *errCatchStack = *pErrCatchStack; dyStringVaPrintf(errCatchStack->message, format, args); dyStringAppendC(errCatchStack->message, '\n'); }
char *hashToRaString(struct hash *hash) /* Convert hash to string in ra format. */ { struct hashEl *el, *list = hashElListHash(hash); struct dyString *dy = dyStringNew(0); slSort(&list, hashElCmp); for (el = list; el != NULL; el = el->next) { dyStringAppend(dy, el->name); dyStringAppendC(dy, ' '); dyStringAppend(dy, el->val); dyStringAppendC(dy, '\n'); } hashElFreeList(&list); return dyStringCannibalize(&dy); }
static void hubConnectRemakeTrackHubVar(struct cart *cart) /* Remake trackHub cart variable if need be from various check box vars. */ { if (cartVarExists(cart, hgHubConnectRemakeTrackHub)) { struct slPair *hubVarList = cartVarsWithPrefix(cart, hgHubConnectHubVarPrefix); int prefixLength = strlen(hgHubConnectHubVarPrefix); struct dyString *trackHubs = dyStringNew(0); struct slPair *hubVar; boolean firstOne = TRUE; for (hubVar = hubVarList; hubVar != NULL; hubVar = hubVar->next) { if (cartBoolean(cart, hubVar->name)) { if (firstOne) firstOne = FALSE; else dyStringAppendC(trackHubs, ' '); dyStringAppend(trackHubs, hubVar->name + prefixLength); } } slPairFreeList(&hubVarList); cartSetString(cart, hubConnectTrackHubsVarName, trackHubs->string); dyStringFree(&trackHubs); cartRemove(cart, hgHubConnectRemakeTrackHub); } }
char *dlListFragWords(struct dlNode *head) /* Return string containing all words in list pointed to by head. */ { struct dyString *dy = dyStringNew(0); dyStringAppendC(dy, '{'); struct dlNode *node; for (node = head; !dlEnd(node); node = node->next) { if (node != head) dyStringAppendC(dy, ' '); struct wordInfo *info = node->val; dyStringAppend(dy, info->word); } dyStringAppendC(dy, '}'); return dyStringCannibalize(&dy); }
boolean raSkipLeadingEmptyLines(struct lineFile *lf, struct dyString *dy) /* Skip leading empty lines and comments. Returns FALSE at end of file. * Together with raNextTagVal you can construct your own raNextRecord.... * If dy parameter is non-null, then the text parsed gets placed into dy. */ { char *line; /* Skip leading empty lines and comments. */ if (dy) dyStringClear(dy); for (;;) { if (!lineFileNext(lf, &line, NULL)) return FALSE; char *tag = skipLeadingSpaces(line); if (tag[0] == 0 || tag[0] == '#') { if (dy) { dyStringAppend(dy, line); dyStringAppendC(dy, '\n'); } } else break; } lineFileReuse(lf); return TRUE; }
void xpTextUntil(struct xp *xp, char *endPattern) /* Stuff xp->text with everything up to endPattern. */ { int endSize = strlen(endPattern); int endPos = 0; char c; struct dyString *dy = xp->stack->text; for (;;) { if ((c = xpGetChar(xp)) == 0) xpUnexpectedEof(xp); if (c == endPattern[endPos]) { endPos += 1; if (endPos == endSize) return; } else { if (endPos > 0) dyStringAppendN(dy, endPattern, endPos); dyStringAppendC(dy, c); endPos = 0; } } }
void makeTableDescriptions(char *database, char *asFile) /* makeTableDescriptions - Add table descriptions to database.. */ { struct sqlConnection *conn = sqlConnect(database); struct lineFile *lf = lineFileOpen(asFile, TRUE); FILE *f = hgCreateTabFile(".", "tableDescriptions"); /* Open a tab file with name corresponding to tableName in tmpDir. */ char *line; /* struct asObject *asList = */ asParseFile(asFile); /* Just to check syntax */ if (sqlTableExists(conn, "chromInfo")) errAbort("%s looks like a genome database, has chromInfo, aborting", database); sqlRemakeTable(conn, "tableDescriptions", "NOSQLINJ CREATE TABLE tableDescriptions (\n" " tableName varchar(255) not null,\n" " autoSqlDef longblob not null,\n" " gbdAnchor varchar(255) not null,\n" " PRIMARY KEY(tableName(32))\n" ")" ); while (lineFileNextReal(lf, &line)) { if (startsWith("table", line)) { struct dyString *as = dyStringNew(0); char *name = trimSpaces(line + 6); /* Skip over table. */ char *escaped = NULL; fprintf(f, "%s\t", name); /* Putting lines into as. */ for (;;) { char *s; dyStringAppend(as, line); dyStringAppendC(as, '\n'); s = skipLeadingSpaces(line); if (s[0] == ')') break; if (!lineFileNext(lf, &line, NULL)) errAbort("Unexpected end of file, missing closing paren in %s", lf->fileName); } escaped = needMem(2*as->stringSize+1); fprintf(f, "%s\t", sqlEscapeTabFileString2(escaped, as->string)); fprintf(f, "\n"); freez(&escaped); dyStringFree(&as); } else errAbort("Expecting table line %d of %s", lf->lineIx, lf->fileName); } hgLoadTabFile(conn, ".", "tableDescriptions", &f); }
char *associationCellVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Make comma separated list of matches to association table. */ { char query[1024]; struct sqlResult *sr; char **row; boolean gotOne = FALSE; struct dyString *dy = newDyString(512); char *result = NULL; char *key = (col->protKey ? (kgVersion == KG_III ? lookupProtein(conn, gp->name) : gp->protein) : gp->name); struct hash *uniqHash = NULL; if (col->weedDupes) uniqHash = newHash(8); safef(query, sizeof(query), col->queryOne, key); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { char *s = row[0]; boolean needQuote; if (uniqHash != NULL) { if (hashLookup(uniqHash, s)) continue; else hashAdd(uniqHash, s, NULL); } needQuote = hasWhiteSpace(s); if (needQuote) dyStringAppendC(dy, '\''); dyStringAppend(dy, s); if (needQuote) dyStringAppendC(dy, '\''); dyStringAppend(dy, ","); gotOne = TRUE; } sqlFreeResult(&sr); if (gotOne) result = cloneString(dy->string); dyStringFree(&dy); freeHash(&uniqHash); return result; }
void dyStringAddList(struct dyString *dy, char *s) /* Add s to end of string. If string is non-empty * first add comma. This make it relatively easy to * build up comma-separates lists. */ { if (dy->stringSize > 0) dyStringAppendC(dy, ','); dyStringAppend(dy, s); }
static struct vcfFile *vcfFileHeaderFromLineFile(struct lineFile *lf, int maxErr) /* Parse a VCF file into a vcfFile object. If maxErr not zero, then * continue to parse until this number of error have been reached. A maxErr * less than zero does not stop and reports all errors. * Set maxErr to VCF_IGNORE_ERRS for silence */ { initVcfSpecInfoDefs(); initVcfSpecGtFormatDefs(); if (lf == NULL) return NULL; struct vcfFile *vcff = vcfFileNew(); vcff->lf = lf; vcff->fileOrUrl = vcfFileCloneStr(vcff, lf->fileName); vcff->maxErr = (maxErr < 0) ? INT_MAX : maxErr; struct dyString *dyHeader = dyStringNew(1024); char *line = NULL; // First, metadata lines beginning with "##": while (lineFileNext(lf, &line, NULL) && startsWith("##", line)) { dyStringAppend(dyHeader, line); dyStringAppendC(dyHeader, '\n'); parseMetadataLine(vcff, line); } slReverse(&(vcff->infoDefs)); slReverse(&(vcff->filterDefs)); slReverse(&(vcff->gtFormatDefs)); // Did we get the bare minimum VCF header with supported version? if (vcff->majorVersion == 0) vcfFileErr(vcff, "missing ##fileformat= header line? Assuming 4.1."); if ((vcff->majorVersion != 4 || (vcff->minorVersion != 0 && vcff->minorVersion != 1)) && (vcff->majorVersion != 3)) vcfFileErr(vcff, "VCFv%d.%d not supported -- only v3.*, v4.0 or v4.1", vcff->majorVersion, vcff->minorVersion); // Next, one header line beginning with single "#" that names the columns: if (line == NULL) // EOF after metadata return vcff; dyStringAppend(dyHeader, line); dyStringAppendC(dyHeader, '\n'); parseColumnHeaderRow(vcff, line); vcff->headerString = dyStringCannibalize(&dyHeader); return vcff; }
boolean raNextTagVal(struct lineFile *lf, char **retTag, char **retVal, struct dyString *dyRecord) // Read next line. Return FALSE at end of file or blank line. Otherwise fill in // *retTag and *retVal and return TRUE. If dy parameter is non-null, then the text parsed // gets appended to dy. Continuation lines in RA file will be joined to produce tag and val, // but dy will be filled with the unedited multiple lines containing the continuation chars. // NOTE: retTag & retVal, if returned, point to static mem which will be overwritten on next call! { *retTag = NULL; *retVal = NULL; char *line, *raw = NULL; int lineLen,rawLen; // Don't bother with raw if it isn't used. char **pRaw = NULL; int *pRawLen = NULL; if (dyRecord != NULL) { pRaw = &raw; pRawLen = &rawLen; } while (lineFileNextFull(lf, &line, &lineLen, pRaw, pRawLen)) // Joins continuation lines { char *clippedText = skipLeadingSpaces(line); if (*clippedText == 0) { if (dyRecord) lineFileReuse(lf); // Just so don't loose leading space in dy. return FALSE; } // Append whatever line was read from file. if (dyRecord) { if (raw != NULL) dyStringAppendN(dyRecord, raw, rawLen); else dyStringAppendN(dyRecord, line, lineLen); dyStringAppendC(dyRecord,'\n'); } // Skip comments if (*clippedText == '#') { if (startsWith("#EOF", clippedText)) return FALSE; else continue; } *retTag = nextWord(&line); *retVal = trimSpaces(line); return TRUE; } return FALSE; }
static void cookieOutput(struct dyString *dy, struct htmlCookie *cookieList) /* Write cookies to dy. */ { struct htmlCookie *cookie; if (cookieList != NULL) { dyStringAppend(dy, "Cookie:"); for (cookie = cookieList; cookie != NULL; cookie = cookie->next) { if (cookie != cookieList) dyStringAppendC(dy, ';'); dyStringAppendC(dy, ' '); dyStringAppend(dy, cookie->name); dyStringAppendC(dy, '='); dyStringAppend(dy, cookie->value); } dyStringAppend(dy, "\r\n"); } }
void outputProtein(struct cdsEvidence *cds, struct dnaSeq *txSeq, FILE *f) /* Translate txSeq to protein guided by cds, and output to file. * The implementation is a little complicated by checking for internal * stop codons and other error conditions. */ { boolean selenocysteine = FALSE; if (selenocysteineHash != NULL) { if (hashLookup(selenocysteineHash, txSeq->name)) selenocysteine = TRUE; } struct dyString *dy = dyStringNew(4*1024); int blockIx; for (blockIx=0; blockIx<cds->cdsCount; ++blockIx) { DNA *dna = txSeq->dna + cds->cdsStarts[blockIx]; int rnaSize = cds->cdsSizes[blockIx]; if (rnaSize%3 != 0) { errAbort("size of block (%d) not multiple of 3 in %s", rnaSize, cds->name); } int aaSize = rnaSize/3; int i; for (i=0; i<aaSize; ++i) { AA aa = lookupCodon(dna); if (aa == 0) { aa = '*'; if (selenocysteine) { if (!isReallyStopCodon(dna, TRUE)) aa = 'U'; } } dyStringAppendC(dy, aa); dna += 3; } } int lastCharIx = dy->stringSize-1; if (dy->string[lastCharIx] == '*') { dy->string[lastCharIx] = 0; dy->stringSize = lastCharIx; } char *prematureStop = strchr(dy->string, '*'); if (prematureStop != NULL) { errAbort("Stop codons in CDS at position %d for %s", (int)(prematureStop - dy->string), cds->name); } faWriteNext(f, cds->name, dy->string, dy->stringSize); dyStringFree(&dy); }
static void addToLabel(struct dyString *label, char *val) /* append a label to the label, separating with a space, do nothing if val is * NULL.*/ { if (val != NULL) { if (label->stringSize > 0) dyStringAppendC(label, ' '); dyStringAppend(label, val); } }
void pf_lineIn(_pf_Stack *stack) /* Get next line of input from stdin. In general * you do not want to mix calls to keyIn and lineIn, * since keyIn is unbuffered and lineIn is buffered. * Returns nil at EOF. */ { char buf[256]; int i, c; FILE *f = stdin; for (i=0; i<sizeof(buf)-1; ++i) { c = fgetc(f); if (c < 0) { if (i == 0) stack[0].String = NULL; else { buf[i] = 0; stack[0].String = _pf_string_from_const(buf); } return; } buf[i] = c; if (c == '\n') { buf[i] = 0; stack[0].String = _pf_string_dupe(buf, i); return; } } /* Well, looks like it's a pretty long string! * Let's convert to dyString based capture rather * than using the fixed size buffer on stack. */ { struct dyString *dy = dyStringNew(512); struct _pf_string *string; dyStringAppendN(dy, buf, i); for (;;) { c = fgetc(f); if (c < 0) break; dyStringAppendC(dy, c); if (c == '\n') break; } string = _pf_string_new(dy->string, dy->bufSize); string->size = dy->stringSize; dyStringCannibalize(&dy); stack[0].String = string; } }
void bamUnpackAux(const bam1_t *bam, struct dyString *dy) /* Unpack the tag:type:val part of bam into dy */ { // adapted from part of bam.c bam_format1: uint8_t *s = bam1_aux(bam); boolean firstTime = TRUE; while (s < bam->data + bam->data_len) { if (firstTime) firstTime = FALSE; else dyStringAppendC(dy, '\t'); dyStringAppendC(dy, *s++); dyStringAppendC(dy, *s++); dyStringAppendC(dy, ':'); dyStringAppendC(dy, s[0]); dyStringAppendC(dy, ':'); uint8_t type = *s++; if (type == 'A') { dyStringPrintf(dy, "%c", *s); ++s; } else if (type == 'C') { dyStringPrintf(dy, "%u", *s); ++s; } else if (type == 'c') { dyStringPrintf(dy, "%d", *s); ++s; } else if (type == 'S') { dyStringPrintf(dy, "%u", *(uint16_t*)s); s += 2; } else if (type == 's') { dyStringPrintf(dy, "%d", *(int16_t*)s); s += 2; } else if (type == 'I') { dyStringPrintf(dy, "%u", *(uint32_t*)s); s += 4; } else if (type == 'i') { dyStringPrintf(dy, "%d", *(int32_t*)s); s += 4; } else if (type == 'f') { dyStringPrintf(dy, "%g", *(float*)s); s += 4; } else if (type == 'd') { dyStringPrintf(dy, "%lg", *(double*)s); s += 8; } else if (type == 'Z' || type == 'H') { dyStringAppend(dy, (char *)s); s += strlen((char *)s) + 1; } } }
char *phyloFindPath(struct phyloTree *tree, char *ref, char *cross) /* find the shortest path from ref to cross (returns a list * of the node names separated by spaces) */ { struct phyloTree *treeRef, *treeCross, *parent; struct dyString *ds = newDyString(0); if ((treeRef = phyloFindName(tree,ref)) == NULL) return NULL; if ((treeCross = phyloFindName(tree,cross)) == NULL) return NULL; phyloClearTreeMarks(tree); phyloMarkUpTree(treeCross); if ((parent = phyloFindMarkUpTree(treeRef)) == NULL) return NULL; /* walk up the tree till we hit the common parent */ while(treeRef != parent) { treeRef = treeRef->parent; if (ds->stringSize) dyStringAppendC(ds, ' '); if (treeRef->ident->name) dyStringAppendN(ds, treeRef->ident->name, strlen(treeRef->ident->name)); } /* now walk down the tree till we come to the target species */ while (parent != treeCross) { parent = parent->mark; dyStringAppendC(ds, ' '); if (parent->ident->name) dyStringAppendN(ds, parent->ident->name, strlen(parent->ident->name)); } return ds->string; }
char *quotedPrintableEncode(char *input) /* Use Quoted-Printable standard to encode a string. */ { struct dyString *dy = dyStringNew(0); size_t i=0,l=strlen(input); int width = 0; for (i=0; i < l; ++i) { char c = input[i]; switch (c) { case '=': case '\t': case '\r': case '\n': case ' ': dyStringAppendC(dy, '='); dyStringPrintf(dy, "%2x", c); width += 3; break; default: dyStringAppendC(dy, c); ++width; } if (width > 72) { dyStringAppendC(dy, '='); dyStringAppendC(dy, '\n'); width = 0; } } /* add terminator to prevent extra newline */ if (lastChar(dy->string) != '=') dyStringAppendC(dy, '='); return dyStringCannibalize(&dy); }
static boolean matchAndExtractIndexes(char *dottedName, struct tagSchema *schema, struct dyString *scratch, char **retIndexes, boolean *retMatchEnd) /* Dotted name is something like this.that.12.more.2.ok * The objArrayPieces is something like "this.that." ".more." ".notOk" * Crucially it holds at least two elements, some of which may be "" * This function will return TRUE if all but maybe the last of the objArrayPieces is * found in the dottedName. If this is the case it will put something like .12.2 in * scratch and *retIndexes. If the last one matches it will set *retMatchEnd. * Sort of a complex routine but it plays a key piece in checking required array * elements */ { struct slName *objArrayPieces = schema->objArrayPieces; dyStringClear(scratch); struct slName *piece = objArrayPieces; char *pos = dottedName; boolean gotNum = FALSE; for (;;) { /* Check to see if we match next piece, and return FALSE if not */ char *pieceString = piece->name; int pieceLen = strlen(pieceString); if (pieceLen != 0 && memcmp(pieceString, pos, pieceLen) != 0) return FALSE; pos += pieceLen; /* Put the number into scratch with a leading dot separator. */ int digits = tagSchemaDigitsUpToDot(pos); if (digits == 0) return FALSE; dyStringAppendC(scratch, '.'); dyStringAppendN(scratch, pos, digits); pos += digits; gotNum = TRUE; /* Go to next piece,saving last piece for outside of the loop. */ piece = piece->next; if (piece->next == NULL) break; } /* One more special case, where last piece needs to agree on emptiness at least in * terms of matching */ if (isEmpty(piece->name) != isEmpty(pos)) return FALSE; /* Otherwise both have something. We return true/false depending on whether it matches */ *retMatchEnd = (strcmp(piece->name, pos) == 0); *retIndexes = scratch->string; return gotNum; }
void bamUnpackCigar(const bam1_t *bam, struct dyString *dyCigar) /* Unpack CIGAR string into dynamic string */ { unsigned int *cigarPacked = bam1_cigar(bam); const bam1_core_t *core = &bam->core; int i; for (i = 0; i < core->n_cigar; i++) { char op; int n = bamUnpackCigarElement(cigarPacked[i], &op); dyStringPrintf(dyCigar, "%d", n); dyStringAppendC(dyCigar, op); } }