Esempio n. 1
0
/**
 * Parse Tokens
 * Description: Takes a TokenList and a Command object and parses the TokenList in order
 *				to generate a command (list of programs in a pipeline);
 * Returns: true on success; false otherwise
 */
bool parseTokens( TokenList tokens, Command * command ) {

	bool success = true;

	Program *currentProgram = command->program = newProgram();
	bool begin = true;

	for (int i = 0; i < tokens.count; i++) {

		char * token = tokens.tokens[i];

		// Check if we are at the beginning of a program
		if ( begin ) {

			if ( strncmp( token, "time", max( strlen( token ), strlen( "time" ) ) ) == 0 ) {

				currentProgram->name = token;
				currentProgram->next = newProgram();
				currentProgram = currentProgram->next;
				begin = true;

				// If we have at least two tokens left and the next one is a pipe
				// then make a blank timed program
				// Note: This doesn't do anything since we don't allow
				//       piped time commands but this would help support it
				//       in the future and it currently prevents better
				//       error checking
				if ( i + 2 < tokens.count && isPipe( tokens.tokens[i+1] ) ) {

					currentProgram->name = NULL;
					currentProgram->next = newProgram();
					currentProgram = currentProgram->next;
					i++;

				}

			// The beginning of a program cannot be <, >, &, or |
			} else if ( !isRedirection( token ) && !isPipe( token ) && !isBackground( token ) ) {

				currentProgram->name = token;
				currentProgram->argv[currentProgram->argc++] = token;

				// Don't come back here again until we process a new program
				begin = false;

			} else {

				error("Program may not start with <, >, |, or &");
				success = false;
				break;

			}

		} else {

			// Process redirection
			if ( isRedirection( token ) ) {

				// Only one level of redirection allowed
				if ( currentProgram->redirect == DEFAULT ) {

					// Need to have at least one token after a redirect
					if ( i+1 < tokens.count ) {

						if ( !isRedirection(tokens.tokens[i+1]) && !isPipe(tokens.tokens[i+1]) 
							&& !isBackground(tokens.tokens[i+1]) ) {

							currentProgram->redirectResource = tokens.tokens[i+1];
							currentProgram->redirect = getRedirect( token );

							// Skip a token
							i++;

						} else {

							error("Expected file after a redirect");
							success = false;
							break;

						}


					} 

					// We can have redirections like <file or >file
					else if ( strlen( token ) > 1 ) {

						currentProgram->redirectResource = token+1;
						currentProgram->redirect = getRedirect( token );

					}
					else {

						error("Expected file after a redirect");
						success = false;
						break;

					}

				} else {

					error("Only one level of redirection allowed");
					success = false;
					break;

				}

			// Process pipe
			} else if ( isPipe( token ) ) {

				// Check if there's a token after this one
				if ( i+1 < tokens.count ) {

					currentProgram->next = newProgram();
					currentProgram = currentProgram->next;
					begin = true;

				}
				else {

					error("Expected program after pipe");
					success = false;
					break;

				}

			// Process background
			} else if ( isBackground( token ) ) {

				// & must be last token
				if ( i+1 >= tokens.count ) 
					command->background = true;
				else {

					error("& can only be placed at end of command");
					success = false;

				}

				break;
			}

			// Plain old argument
			else
				currentProgram->argv[currentProgram->argc++] = token;
		}

	}

	return success;
}
Esempio n. 2
0
/* Could be a file or a stream. */
void svd_closeFile(FILE *file) {
  if (file == stdin || file == stdout) return;
  if (isPipe(file)) pclose(file);
  else fclose(file);
}
Esempio n. 3
0
void chainNet(char *chainFile, char *tSizes, char *qSizes, 
	char *tNet, char *qNet)
/* chainNet - Make alignment nets out of chains. */
{
struct lineFile *lf = lineFileOpen(chainFile, TRUE);
struct hash *qHash, *tHash;
struct chrom *qChromList, *tChromList, *tChrom, *qChrom;
struct chain *chain;
double lastScore = -1;
struct lm *lm = lmInit(0);
struct rbTreeNode **rbStack;
FILE *tNetFile = mustOpen(tNet, "w");
FILE *qNetFile = mustOpen(qNet, "w");


lmAllocArray(lm, rbStack, 256);
makeChroms(qSizes, lm, rbStack, &qHash, &qChromList);
makeChroms(tSizes, lm, rbStack, &tHash, &tChromList);
verbose(1, "Got %d chroms in %s, %d in %s\n", slCount(tChromList), tSizes,
       slCount(qChromList), qSizes);
lineFileSetMetaDataOutput(lf, tNetFile);
lineFileSetMetaDataOutput(lf, qNetFile);

/* Loop through chain file building up net. */
while ((chain = chainRead(lf)) != NULL)
    {
    /* Make sure that input is really sorted. */
    if (lastScore >= 0 && chain->score > lastScore)
        errAbort("%s must be sorted in order of score", chainFile);
    lastScore = chain->score;

    if (chain->score < minScore) 
	{
    	break;
	}
    verbose(2, "chain %f (%d els) %s %d-%d %c %s %d-%d\n", 
	    chain->score, slCount(chain->blockList), 
	    chain->tName, chain->tStart, chain->tEnd, 
	    chain->qStrand, chain->qName, chain->qStart, chain->qEnd);
    qChrom = hashMustFindVal(qHash, chain->qName);
    if (qChrom->size != chain->qSize)
        errAbort("%s is %d in %s but %d in %s", chain->qName, 
		chain->qSize, chainFile,
		qChrom->size, qSizes);
    tChrom = hashMustFindVal(tHash, chain->tName);
    if (tChrom->size != chain->tSize)
        errAbort("%s is %d in %s but %d in %s", chain->tName, 
		chain->tSize, chainFile,
		tChrom->size, tSizes);
    if (!inclQuery(chain))
        verbose(2, "skipping chain on query %s\n", chain->qName);
    else
        {
        addChain(qChrom, tChrom, chain);
        verbose(2, "%s has %d inserts, %s has %d\n", tChrom->name, 
                tChrom->spaces->n, qChrom->name, qChrom->spaces->n);
        }
    }
/* Build up other side of fills.  It's just for historical 
 * reasons this is not done during the main build up.   
 * It's a little less efficient this way, but to change it
 * some hard reverse strand issues would have to be juggled. */
verbose(1, "Finishing nets\n");
finishNet(qChromList, TRUE);
finishNet(tChromList, FALSE);

/* Write out basic net files. */
verbose(1, "writing %s\n", tNet);
outputNetSide(tChromList, tNetFile, FALSE);
verbose(1, "writing %s\n", qNet);
outputNetSide(qChromList, qNetFile, TRUE);

/* prevent SIGPIPE in preceding process if input is a pipe, consume remainder
 * of input file since we stop before EOF. */
if (isPipe(lf->fd))
    {
    char *line;
    while(lineFileNext(lf, &line, NULL))
        continue;
    }
lineFileClose(&lf);

if (verboseLevel() > 1)
    printMem(stderr);
}