forked from uva-cs/pdr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ibcm-parse.cpp
120 lines (107 loc) · 3.94 KB
/
ibcm-parse.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* 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;
}