/* A program that will quickly check if the file names passed in via * command line arguments look like IBCM files. In particular, it * checks if the first four digits on each line are all hexadecimal * digits. It does not program validity checking beyond this. It is * useful to tell the students if, on submission, their programs will * parse correctly in an IBCM simulator. */ #include <iostream> #include <fstream> #include <stdlib.h> #include <ctype.h> #include <string.h> using namespace std; void printHelp(char* name); bool isEmpty(string& line); int main (int argc, char *argv[]) { string line; int linenum = 0; bool allowComments = false; // make sure they gave some command-line parameters if ( argc == 1 ) { cout << argv[0] << ": no input files" << endl; exit(1); } for ( int i = 1; i < argc; i++ ) { // print the help description if ( !strcmp(argv[i], "-help") ) { printHelp(argv[0]); exit(0); } // a comment has a '#' as the first character on a line or // a comment has a '//' as the first two characters on a line if ( !strcmp(argv[i],"-allowcomments") ) { allowComments = true; continue; } if ( argv[i][0] == '-' ) { cout << argv[0] << ": " << argv[i] << ": no such argument" << endl; printHelp(argv[0]); exit(1); } // open the file ifstream file(argv[i]); if ( !file.is_open() ) { cout << argv[0] << ": " << argv[i] << ": no such file" << endl; exit(2); } // read in the entire file... while ( file.good() ) { // read in a line from the file getline (file, line); linenum++; // is it the last line of the file? if ( (line.size() == 0) && (!file.good()) ) break; // is the line empty or all whitespace? if ( isEmpty(line) ) continue; // is it a `//` comment? else if ( allowComments && (line.size() >= 2) && (line[0] == '/') && (line[1] == '/') ) continue; // is it a `#` comment? else if ( allowComments && (line.size() >= 1) && (line[0] == '#') ) continue; // is the line too short? else if ( line.size() < 4 ) { cout << argv[0] << ": " << argv[i] << " has too short a line on line number " << linenum << "(" << line.size() << ")" << endl; exit(3); } // are the first four digits hex characters? for ( int j = 0; j < 4; j++ ) if ( !isxdigit(line[j]) ) { cout << argv[0] << ": " << argv[i] << " invalid hexadecimal digit '" << line[j] << "' on line " << linenum << " character " << (j+1) << endl; exit(3); } } // all done with this file! file.close(); } return 0; } void printHelp(char *name) { static bool helpPrinted; // Static values are initialized to 0 or 0-equivalent if(helpPrinted) return; helpPrinted = true; cout << "Usage: " << name << " [option] <inputfile>" << endl; cout << "Options:" << endl; cout << "\t[-allowcomments]\tAllows file specified by <inputfile> to contain" << endl << "\t\t\t\tlines beginning with `//` and `#`." << endl; cout << "\t[-help]\t\t\tPrints this help message." << endl; } bool isEmpty(string& line) { // is the line empty? if ( line.empty() ) { return true; } // does the line contain spaces or carriage returns? else if ( line.find_first_not_of(' ') != line.npos && line.find_first_not_of('\n') != line.npos && line.find_first_not_of('\r') != line.npos) { return false; } // otherwise, the line is basically empty return true; }