bool Lexer::tokenizeLine() { while(m_begin != m_end && isspace(*m_begin)) { ++m_begin; } // We got an end of a line or a comment. if(m_begin == m_end || *m_begin == ';') { return true; } if(*m_begin == '(') { m_tokens.push_back(Token(Token::tok_leftParen, line(), column())); ++m_begin; return tokenizeLine(); } if(*m_begin == ')') { m_tokens.push_back(Token(Token::tok_rightParen, line(), column())); ++m_begin; return tokenizeLine(); } if(*m_begin == '"') { return tokenizeString() && tokenizeLine(); } if(isIdentifier(*m_begin)) { return tokenizeIdentifier() && tokenizeLine(); } OGDF_ERROR("Unexpected character \"" << *m_begin << "\" at (" << line() << ", " << column() << ")."); return false; }
// The line is a continuation of a previous one if: // 1. it starts with space or horizontal tab; // 2. it contains at least one token. void CPatternsFileProcessor::ReadPattern( CTokens& patternTokens ) { patternTokens.clear(); check_logic( file.is_open() ); check_logic( !tokenizer.empty() ); check_logic( !errorProcessor.HasCriticalErrors() ); if( lineStartsWithSpace() ) { errorProcessor.AddError( CError( CLineSegment( 0, tokenizer.front()->Offset + 1 ), CSharedFileLine( line, lineNumber ), "a pattern definition is required to be" " written from the first character of the line" ) ); } line.clear(); // read rest lines of pattern while( file.good() ) { readLine(); if( !lineStartsWithSpace() ) { break; } if( !tokenizeLine() ) { line.clear(); break; } } patternTokens = move( tokenizer ); skipEmptyLines(); }
void InputDeck::parseCells( LineExtractor& lines ){ std::string line; token_list_t token_buffer; while( !isblank(line = lines.takeLine()) ){ tokenizeLine(line, token_buffer, "="); if( do_line_continuation( lines, token_buffer ) ){ continue; } if( OPT_DEBUG ) std::cout << "Creating cell with the following tokens:\n" << token_buffer << std::endl; CellCard* c = new CellCardImpl(*this, token_buffer); if( OPT_VERBOSE ) c->print(std::cout); this->cells.push_back(c); this->cell_map.insert( std::make_pair(c->getIdent(), c) ); token_buffer.clear(); } }
bool Script::setData(const QString& str) { m_data = str; // Construct individual code lines from the data m_lines.clear(); if (m_data.isEmpty() == false) { QStringList lines = m_data.split(QRegExp("(\r\n|\n\r|\r|\n)"), QString::KeepEmptyParts); foreach (QString line, lines) m_lines << tokenizeLine(line + QString("\n")); } // Map all labels to their individual line numbers for fast jumps m_labels.clear(); for (int i = 0; i < m_lines.size(); i++) { QList <QStringList> line = m_lines[i]; if (line.isEmpty() == false && line.first().size() == 2 && line.first()[0] == Script::labelCmd) { m_labels[line.first()[1]] = i; } } return true; }
Tokenizer::Tokenizer(std::vector<std::string> fileVec, FileStructure fstruc) { size = fileVec.size(); buildKeywords(); for (unsigned int i = 0; i < fileVec.size(); i++) { lines.push_back(tokenizeLine(i, fileVec[i], fstruc)); } }
bool Lexer::tokenize() { cleanValues(); m_tokens.clear(); m_line = 0; while(fetchBuffer()) { if(!tokenizeLine()) { return false; } } return true; }
// skips empty lines (lines without any tokens) // returns true if not empty line found bool CPatternsFileProcessor::skipEmptyLines() { tokenizer.Reset(); while( !errorProcessor.HasCriticalErrors() && !tokenizeLine() && file.good() ) { readLine(); } if( tokenizer.empty() || errorProcessor.HasCriticalErrors() ) { reset(); return false; } return true; }
/* * Tokenize a file, and return a vector of tokens */ std::vector<FixieTokenizer::token> *FixieTokenizer::tokenize(std::ifstream *file) { std::vector<FixieTokenizer::token> *tokens = new std::vector<FixieTokenizer::token>(); std::string line; int lineNumber = 0; //Read off the lines into the tokenizer while (file->good()) { lineNumber++; getline(*file,line); //The tokenizer takes a vector as an argument, and //pumps its tokens into that vector tokenizeLine(lineNumber,line,tokens); } return tokens; }
bool Script::setData(const QString& str) { m_data = str; m_syntaxErrorLines.clear(); // Construct individual code lines from the data m_lines.clear(); if (m_data.isEmpty() == false) { int i = 1; QStringList lines = m_data.split(QRegExp("(\r\n|\n\r|\r|\n)"), QString::KeepEmptyParts); foreach (QString line, lines) { bool ok = false; if (line.isEmpty() == false) { m_lines << tokenizeLine(line + QString("\n"), &ok); if (ok == false) m_syntaxErrorLines.append(i); } i++; }
void InputDeck::parseSurfaces( LineExtractor& lines ){ std::string line; token_list_t token_buffer; while( !isblank(line = lines.takeLine()) ){ tokenizeLine(line, token_buffer ); if( do_line_continuation( lines, token_buffer ) ){ continue; } SurfaceCard* s = new SurfaceCard(*this, token_buffer); if( OPT_VERBOSE) s->print(std::cout); this->surfaces.push_back(s); this->surface_map.insert( std::make_pair(s->getIdent(), s) ); token_buffer.clear(); } }
/* ** This is the main routine. This routine runs first. It processes ** command-line arguments then runs the test. */ int main(int argc, char **argv){ int verifyMode = 0; /* True if in -verify mode */ int haltOnError = 0; /* Stop on first error if true */ int enableTrace = 0; /* Trace SQL statements if true */ const char *zScriptFile = 0; /* Input script filename */ const char *zDbEngine = "SQLite"; /* Name of database engine */ const char *zConnection = 0; /* Connection string on DB engine */ const DbEngine *pEngine = 0; /* Pointer to DbEngine object */ int i; /* Loop counter */ char *zScript; /* Content of the script */ long nScript; /* Size of the script in bytes */ void *pConn; /* Connection to the database engine */ int rc; /* Result code from subroutine call */ int nErr = 0; /* Number of errors */ int nCmd = 0; /* Number of SQL statements processed */ int nSkipped = 0; /* Number of SQL statements skipped */ int nResult; /* Number of query results */ char **azResult; /* Query result vector */ Script sScript; /* Script parsing status */ FILE *in; /* For reading script */ char zHash[100]; /* Storage space for hash results */ int hashThreshold = DEFAULT_HASH_THRESHOLD; /* Threshold for hashing res */ int bHt = 0; /* True if -ht command-line option */ const char *zParam = 0; /* Argument to -parameters */ /* Add calls to the registration procedures for new database engine ** interfaces here */ registerSqlite(); #ifndef OMIT_ODBC registerODBC3(); #endif /* Report an error if no registered engines */ if( nEngine == 0 ){ fprintf(stderr, "%s: No registered database engines\n", argv[0]); usage(argv[0]); } /* Default to first registered engine */ if( zDbEngine == NULL ){ zDbEngine = apEngine[0]->zName; } /* Scan the command-line and process arguments */ for(i=1; i<argc; i++){ int n; const char *z = argv[i]; if( z[0]=='-' && z[1]=='-' ) z++; n = (int)strlen(z); if( strncmp(z, "-connection",n)==0 ){ zConnection = argv[++i]; }else if( strncmp(z, "-engine",n)==0 ){ zDbEngine = argv[++i]; }else if( strncmp(z, "-halt",n)==0 ){ haltOnError = 1; }else if( strncmp(z, "-ht",n)==0 ){ hashThreshold = atoi(argv[++i]); bHt = -1; }else if( strncmp(z, "-odbc",n)==0 ){ zDbEngine = "ODBC3"; zConnection = argv[++i]; }else if( strncmp(z, "-parameters",n)==0 ){ zParam = argv[++i]; }else if( strncmp(z, "-trace",n)==0 ){ enableTrace = 1; }else if( strncmp(z, "-verify",n)==0 ){ verifyMode = 1; }else if( zScriptFile==0 ){ zScriptFile = z; }else{ fprintf(stderr, "%s: unknown argument: %s\n", argv[0], argv[i]); usage(argv[0]); } } /* Check for errors and missing arguments. Find the database engine ** to use for this run. */ if( zScriptFile==0 ){ fprintf(stderr, "%s: no input script specified\n", argv[0]); usage(argv[0]); } for(i=0; i<nEngine; i++){ if( stricmp(zDbEngine, apEngine[i]->zName)==0 ){ pEngine = apEngine[i]; break; } } if( pEngine==0 ){ fprintf(stderr, "%s: unknown database engine: %s\n", argv[0], zDbEngine); fprintf(stdout, "Choices are:"); for(i=0; i<nEngine; i++) fprintf(stdout, " %s", apEngine[i]->zName); fprintf(stdout, "\n"); exit(1); } /* ** Read the entire script file contents into memory */ in = fopen(zScriptFile, "rb"); if( in==0 ){ fprintf(stderr, "%s: cannot open for reading\n", zScriptFile); exit(1); } fseek(in, 0L, SEEK_END); nScript = ftell(in); zScript = malloc( nScript+1 ); if( zScript==0 ){ fprintf(stderr, "out of memory at %s:%d\n", __FILE__,__LINE__); exit(1); } fseek(in, 0L, SEEK_SET); fread(zScript, 1, nScript, in); fclose(in); zScript[nScript] = 0; /* Initialize the sScript structure so that the cursor will be pointing ** to the start of the first line in the file after nextLine() is called ** once. */ memset(&sScript, 0, sizeof(sScript)); sScript.zScript = zScript; sScript.zLine = zScript; sScript.iEnd = nScript; sScript.copyFlag = !verifyMode; /* Open the database engine under test */ rc = pEngine->xConnect(pEngine->pAuxData, zConnection, &pConn, zParam); if( rc ){ fprintf(stderr, "%s: unable to connect to database\n", argv[0]); exit(1); } /* Get the "real" db name */ rc = pEngine->xGetEngineName(pConn, &zDbEngine); if( rc ){ fprintf(stderr, "%s: unable to get DB name from connection\n", argv[0]); exit(1); } /* Loop over all records in the file */ while( (nErr==0 || !haltOnError) && findStartOfNextRecord(&sScript) ){ int bSkip = 0; /* True if we should skip the current record. */ /* Tokenizer the first line of the record. This also records the ** line number of the first record in sScript.startLine */ tokenizeLine(&sScript); bSkip = 0; while( strcmp(sScript.azToken[0],"skipif")==0 || strcmp(sScript.azToken[0],"onlyif")==0 ){ int bMatch; /* The "skipif" and "onlyif" modifiers allow skipping or using ** statement or query record for a particular database engine. ** In this way, SQL features implmented by a majority of the ** engines can be tested without causing spurious errors for ** engines that don't support it. ** ** Once this record is encountered, an the current selected ** db interface matches the db engine specified in the record, ** the we skip this rest of this record for "skipif" or for ** "onlyif" we skip the record if the record does not match. */ bMatch = stricmp(sScript.azToken[1], zDbEngine)==0; if( sScript.azToken[0][0]=='s' ){ if( bMatch ) bSkip = -1; }else{ if( !bMatch ) bSkip = -1; } nextLine(&sScript); tokenizeLine(&sScript); } if( bSkip ) { int n; nSkipped++; if( !verifyMode ) continue; if( strcmp(sScript.azToken[0],"query")!=0 ) continue; if( sScript.azToken[3][0]==0 ) continue; /* We are skipping this record. But we observe that it is a query ** with a named hash value and we are in verify mode. Even though ** we are going to skip the SQL evaluation, we might as well check ** the hash of the result. */ while( !nextIsBlank(&sScript) && nextLine(&sScript) && strcmp(sScript.zLine,"----")!=0 ){ /* Skip over the SQL text */ } if( strcmp(sScript.zLine, "----")==0 ) nextLine(&sScript); if( sScript.zLine[0]==0 ) continue; n = sscanf(sScript.zLine, "%*d values hashing to %32s", zHash); if( n!=1 ){ md5_add(sScript.zLine); md5_add("\n"); while( !nextIsBlank(&sScript) && nextLine(&sScript) ){ md5_add(sScript.zLine); md5_add("\n"); } strcpy(zHash, md5_finish()); } if( checkValue(sScript.azToken[3], zHash) ){ fprintf(stderr, "%s:%d: labeled result [%s] does not agree with " "previous values\n", zScriptFile, sScript.startLine, sScript.azToken[3]); nErr++; } continue; } /* Figure out the record type and do appropriate processing */ if( strcmp(sScript.azToken[0],"statement")==0 ){ int k = 0; int bExpectOk = 0; int bExpectError = 0; /* Extract the SQL from second and subsequent lines of the ** record. Copy the SQL into contiguous memory at the beginning ** of zScript - we are guaranteed to have enough space there. */ while( nextLine(&sScript) && sScript.zLine[0] ){ if( k>0 ) zScript[k++] = '\n'; memmove(&zScript[k], sScript.zLine, sScript.len); k += sScript.len; } zScript[k] = 0; bExpectOk = strcmp(sScript.azToken[1],"ok")==0; bExpectError = strcmp(sScript.azToken[1],"error")==0; /* Run the statement. Remember the results ** If we're expecting an error, pass true to suppress ** printing of any errors. */ if( enableTrace ) printf("%s;\n", zScript); rc = pEngine->xStatement(pConn, zScript, bExpectError); nCmd++; /* Check to see if we are expecting success or failure */ if( bExpectOk ){ /* do nothing if we expect success */ }else if( bExpectError ){ /* Invert the result if we expect failure */ rc = !rc; }else{ fprintf(stderr, "%s:%d: statement argument should be 'ok' or 'error'\n", zScriptFile, sScript.startLine); nErr++; rc = 0; } /* Report an error if the results do not match expectation */ if( rc ){ fprintf(stderr, "%s:%d: statement error\n", zScriptFile, sScript.startLine); nErr++; } }else if( strcmp(sScript.azToken[0],"query")==0 ){ int k = 0; int c; /* Verify that the type string consists of one or more characters ** from the set "TIR". */ for(k=0; (c = sScript.azToken[1][k])!=0; k++){ if( c!='T' && c!='I' && c!='R' ){ fprintf(stderr, "%s:%d: unknown type character '%c' in type string\n", zScriptFile, sScript.startLine, c); nErr++; break; } } if( c!=0 ) continue; if( k<=0 ){ fprintf(stderr, "%s:%d: missing type string\n", zScriptFile, sScript.startLine); nErr++; break; } /* Extract the SQL from second and subsequent lines of the record ** until the first "----" line or until end of record. */ k = 0; while( !nextIsBlank(&sScript) && nextLine(&sScript) && sScript.zLine[0] && strcmp(sScript.zLine,"----")!=0 ){ if( k>0 ) zScript[k++] = '\n'; memmove(&zScript[k], sScript.zLine, sScript.len); k += sScript.len; } zScript[k] = 0; /* Run the query */ nResult = 0; azResult = 0; if( enableTrace ) printf("%s;\n", zScript); rc = pEngine->xQuery(pConn, zScript, sScript.azToken[1], &azResult, &nResult); nCmd++; if( rc ){ fprintf(stderr, "%s:%d: query failed\n", zScriptFile, sScript.startLine); pEngine->xFreeResults(pConn, azResult, nResult); nErr++; continue; } /* Do any required sorting of query results */ if( sScript.azToken[2][0]==0 || strcmp(sScript.azToken[2],"nosort")==0 ){ /* Do no sorting */ }else if( strcmp(sScript.azToken[2],"rowsort")==0 ){ /* Row-oriented sorting */ nColumn = (int)strlen(sScript.azToken[1]); qsort(azResult, nResult/nColumn, sizeof(azResult[0])*nColumn, rowCompare); }else if( strcmp(sScript.azToken[2],"valuesort")==0 ){ /* Sort all values independently */ nColumn = 1; qsort(azResult, nResult, sizeof(azResult[0]), rowCompare); }else{ fprintf(stderr, "%s:%d: unknown sort method: '%s'\n", zScriptFile, sScript.startLine, sScript.azToken[2]); nErr++; } /* Hash the results if we are over the hash threshold or if we ** there is a hash label */ if( sScript.azToken[3][0] || (hashThreshold>0 && nResult>hashThreshold) ){ md5_add(""); /* make sure md5 is reset, even if no results */ for(i=0; i<nResult; i++){ md5_add(azResult[i]); md5_add("\n"); } sqlite3_snprintf(sizeof(zHash), zHash, "%d values hashing to %s", nResult, md5_finish()); sScript.azToken[3][20] = 0; if( sScript.azToken[3][0] && checkValue(sScript.azToken[3], md5_finish()) ){ fprintf(stderr, "%s:%d: labeled result [%s] does not agree with " "previous values\n", zScriptFile, sScript.startLine, sScript.azToken[3]); nErr++; } } if( verifyMode ){ /* In verify mode, first skip over the ---- line if we are still ** pointing at it. */ if( strcmp(sScript.zLine, "----")==0 ) nextLine(&sScript); /* Compare subsequent lines of the script against the results ** from the query. Report an error if any differences are found. */ if( hashThreshold==0 || nResult<=hashThreshold ){ for(i=0; i<nResult && sScript.zLine[0]; nextLine(&sScript), i++){ if( strcmp(sScript.zLine, azResult[i])!=0 ){ fprintf(stdout,"%s:%d: wrong result\n", zScriptFile, sScript.nLine); nErr++; break; } } }else{ if( strcmp(sScript.zLine, zHash)!=0 ){ fprintf(stderr, "%s:%d: wrong result hash\n", zScriptFile, sScript.nLine); nErr++; } } }else{ /* In completion mode, first make sure we have output an ---- line. ** Output such a line now if we have not already done so. */ if( strcmp(sScript.zLine, "----")!=0 ){ printf("----\n"); } /* Output the results obtained by running the query */ if( hashThreshold==0 || nResult<=hashThreshold ){ for(i=0; i<nResult; i++){ printf("%s\n", azResult[i]); } }else{ printf("%s\n", zHash); } printf("\n"); /* Skip over any existing results. They will be ignored. */ sScript.copyFlag = 0; while( sScript.zLine[0]!=0 && sScript.iCur<sScript.iEnd ){ nextLine(&sScript); } sScript.copyFlag = 1; } /* Free the query results */ pEngine->xFreeResults(pConn, azResult, nResult); }else if( strcmp(sScript.azToken[0],"hash-threshold")==0 ){ /* Set the maximum number of result values that will be accepted ** for a query. If the number of result values exceeds this number, ** then an MD5 hash is computed of all values, and the resulting hash ** is the only result. ** ** If the threshold is 0, then hashing is never used. ** ** If a threshold was specified on the command line, ignore ** any specifed in the script. */ if( !bHt ){ hashThreshold = atoi(sScript.azToken[1]); } }else if( strcmp(sScript.azToken[0],"halt")==0 ){ /* Used for debugging. Stop reading the test script and shut down. ** A "halt" record can be inserted in the middle of a test script in ** to run the script up to a particular point that is giving a ** faulty result, then terminate at that point for analysis. */ fprintf(stdout, "%s:%d: halt\n", zScriptFile, sScript.startLine); break; }else{ /* An unrecognized record type is an error */ fprintf(stderr, "%s:%d: unknown record type: '%s'\n", zScriptFile, sScript.startLine, sScript.azToken[0]); nErr++; break; } } /* Shutdown the database connection. */ rc = pEngine->xDisconnect(pConn); if( rc ){ fprintf(stderr, "%s: disconnection from database failed\n", argv[0]); nErr++; } /* Report the number of errors and quit. */ if( verifyMode || nErr || nSkipped){ fprintf(stderr, "%d errors out of %d tests in %s - %d skipped.", nErr, nCmd, zScriptFile, nSkipped); if( zParam ) fprintf(stderr, " [%s]", zParam); fprintf(stderr, "\n"); } free(zScript); return nErr; }
void processLine( char *s, unsigned *count, char **vector[] ) { char *t; char *u; size_t m; size_t n; BOOL allocFlag = FALSE; if (!(t = _tcschr(s,'"'))) { // no quoted strings, tokenizeLine(s,count,vector); // just standard fare } else { // There are two kinds of situations in which quotes can occur: // 1. "FOO = bar baz" // 2. FOO="bar baz" if ((t == s) || (*(t-1) != '=')) { // Case 1 above *t++ = '\0'; // quoted macrodef tokenizeLine(s,count,vector); // get tokens before " } else { // Case 2 above *t-- = ' '; for (u = t; u > s; --u) // find the beginning of the macro name if (*u == ' ' || *u == '\t' || *u == '\n') break; if (u != s) { *u++ = '\0'; tokenizeLine(s, count, vector); } t = u; } n = _tcslen(t); for (u = t; *u; ++u) { // look for closing " if (*u == '"') { // need " and not "" if (*(u+1) == '"') { _tcscpy(u,u+1); continue; } *u++ = '\0'; // terminate macrodef addArgument(t,*count,vector); // treat as one arg ++*count; processLine(u+1,count,vector); // recurse on rest of line break; } // TAIL RECURSION if ((*u == '\\') && WHITESPACE(*(u-1)) && (*(u+1) == '\n')) { // \n always last char *u = '\0'; // 2 chars go to 1 m = (n = n-2); // adjust length count if (!allocFlag) { allocFlag = TRUE; t = makeString(t); } getRestOfLine(&t,&n); // get some more text u = t + m ; // reset u & continue looping } } if (u == t + n) { // if at end of line makeError(0,SYNTAX_NO_QUOTE); // and no ", error } if (allocFlag) { FREE(t); } } }
void InputDeck::parseDataCards( LineExtractor& lines ){ std::string line; token_list_t token_buffer; while( lines.hasLine() && !isblank(line = lines.takeLine()) ){ tokenizeLine(line, token_buffer ); if( do_line_continuation( lines, token_buffer ) ){ continue; } else if( token_buffer.at(0) == "#" ){ std::cerr << "Vertical data card format not supported" << std::endl; std::cerr << "Data written in this format will be ignored." << std::endl; } DataCard* d = NULL; DataCard::kind t = DataCard::OTHER; int ident = 0; std::string cardname = token_buffer.at(0); token_buffer.erase( token_buffer.begin() ); if( cardname.find("tr") == 0 || cardname.find("*tr") == 0 ){ t = DataCard::TR; bool degree_format = false; if( cardname[0] == '*' ){ degree_format = true; cardname = cardname.substr( 1 ); // remove leading * } else if( cardname.find("*") == cardname.length()-1 ){ // although it's undocumented, apparently TRn* is a synonym for *TRn // (the manual uses this undocumented form in chapter 4) degree_format = true; cardname.resize( cardname.length() -1 ); // remove trailing * } std::string id_string( cardname, 2 ); // the id_string may be empty, indicating that n is missing from TRn. // examples from the manual indicate it should be assumed to be 1 if( id_string == "" ){ ident = 1; } else{ ident = makeint( id_string ); } d = new TransformCard( *this, ident, degree_format, token_buffer); } if(d){ if( OPT_VERBOSE ){ d->print( std::cout ); } this->datacards.push_back(d); this->datacard_map.insert( std::make_pair( std::make_pair(t,ident), d) ); } token_buffer.clear(); } }
DWORD VmKdcGetUpnKeysMitDb( char *upn, char *dumpFile, char **ppRetPrincName, PVMKDC_KEYSET *ppRetKeySet) { DWORD dwError = 0; FILE *fp = NULL; char *line = NULL; char *princName = NULL; size_t upnLen = strlen(upn); int found = 0; PVMKDC_KEYSET keySet = NULL; fp = fopen(dumpFile, "r"); if (!fp) { dwError = EINVAL; goto error; } line = fgets_long(fp); while (line) { if (princName) { free(princName); } dwError = tokenizeLine(line, &princName, &keySet); if (dwError == ENOMEM) { goto error; } else if (dwError == EINVAL) { if (line) { free(line); line = NULL; } line = fgets_long(fp); continue; } if (strncmp(upn, princName, upnLen) == 0) { found = 1; break; } else { if (princName) { free(princName); princName = NULL; } VMKDC_SAFE_FREE_KEYSET(keySet); } if (line) { free(line); line = NULL; } line = fgets_long(fp); } if (found) { *ppRetKeySet = keySet; if (ppRetPrincName) { *ppRetPrincName = princName; princName = NULL; } } error: if (line) { free(line); } if (fp) { fclose(fp); } if (!found) { VMKDC_SAFE_FREE_KEYSET(keySet); } if (princName) { free(princName); } return dwError; }
int main(int argc, char *argv[]) { char *line = NULL; char *princName = NULL; FILE *infp = NULL; PVMKDC_KEYSET key = NULL; int i=0; int sts = 0; if (argc == 1) { fprintf(stderr, "usage: %s dumpfile\n", argv[0]); return 1; } sts = VmKdcGetUpnKeysMitDb( "K/M@", argv[1], &princName, &key); if (sts == 0) { printKeyEntry(princName, key); free(princName); princName = NULL; VMKDC_SAFE_FREE_KEYSET(key); } infp = fopen(argv[1], "r"); if (!infp) { fprintf(stderr, "fopen(%s) failed\n", argv[1]); return 1; } line = fgets_long(infp); while (line) { i++; if (princName) { free(princName); princName = NULL; } sts = tokenizeLine(line, &princName, &key); if (sts == 0 && princName && key) { printKeyEntry(princName, key); printf("\n"); } VMKDC_SAFE_FREE_KEYSET(key); free(line); line = fgets_long(infp); } if (infp) { fclose(infp); } if (line) { free(line); } if (princName) { free(princName); } return 0; }