aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/bin2cpp.cpp414
-rw-r--r--src/tools/mkunit.cpp962
-rw-r--r--src/tools/myriad.cpp438
-rw-r--r--src/tools/viewcsv.cpp868
4 files changed, 1341 insertions, 1341 deletions
diff --git a/src/tools/bin2cpp.cpp b/src/tools/bin2cpp.cpp
index 0b822f0..4214b34 100644
--- a/src/tools/bin2cpp.cpp
+++ b/src/tools/bin2cpp.cpp
@@ -16,244 +16,244 @@ using namespace Bu;
16class Options : public OptParser 16class Options : public OptParser
17{ 17{
18public: 18public:
19 Options( int argc, char *argv[] ) : 19 Options( int argc, char *argv[] ) :
20 sClass("Datafiles") 20 sClass("Datafiles")
21 { 21 {
22 addHelpBanner("bin2cpp - convert files into executable-embeddable C++ code.\n"); 22 addHelpBanner("bin2cpp - convert files into executable-embeddable C++ code.\n");
23 addHelpBanner("Each file in the input is loaded, filtered according to your options, and written as stack allocated, static variables in a generated class. You can then access the files as though they were on disk through that class."); 23 addHelpBanner("Each file in the input is loaded, filtered according to your options, and written as stack allocated, static variables in a generated class. You can then access the files as though they were on disk through that class.");
24 addHelpBanner("\nUsage: bin2cpp [options] [input1] [input2] [...] [inputN]"); 24 addHelpBanner("\nUsage: bin2cpp [options] [input1] [input2] [...] [inputN]");
25 addHelpBanner( " Or: bin2cpp -s <taf spec file>\n"); 25 addHelpBanner( " Or: bin2cpp -s <taf spec file>\n");
26 addOption( sClass, 'c', "Class name [default=\"Datafiles\"]"); 26 addOption( sClass, 'c', "Class name [default=\"Datafiles\"]");
27 addOption( sOutBase, 'o', "Output base filename [defaults to classname]"); 27 addOption( sOutBase, 'o', "Output base filename [defaults to classname]");
28 addOption( sOutDir, 'd', "Output directory [defaults to current dir]"); 28 addOption( sOutDir, 'd', "Output directory [defaults to current dir]");
29 addOption( slot(this, &Options::addFilter), 'f', "Add filter: deflate, bzip2, lzma, base64, hex"); 29 addOption( slot(this, &Options::addFilter), 'f', "Add filter: deflate, bzip2, lzma, base64, hex");
30 addOption( sSpecFile, 's', "Use the specified spec file instead of providing options on the command line. If you use this option all others are ignored."); 30 addOption( sSpecFile, 's', "Use the specified spec file instead of providing options on the command line. If you use this option all others are ignored.");
31 setNonOption( slot(this, &Options::addInput) ); 31 setNonOption( slot(this, &Options::addInput) );
32 addHelpOption(); 32 addHelpOption();
33 33
34 parse( argc, argv ); 34 parse( argc, argv );
35 35
36 if( !sOutBase.isSet() ) 36 if( !sOutBase.isSet() )
37 sOutBase = sClass.toLower(); 37 sOutBase = sClass.toLower();
38 if( sOutDir.isSet() ) 38 if( sOutDir.isSet() )
39 sOutDir += "/"; 39 sOutDir += "/";
40 } 40 }
41 41
42 virtual ~Options() 42 virtual ~Options()
43 { 43 {
44 } 44 }
45 45
46 int addFilter( Bu::StrArray aArgs ) 46 int addFilter( Bu::StrArray aArgs )
47 { 47 {
48 slFilter.append( aArgs[1] ); 48 slFilter.append( aArgs[1] );
49 return 1; 49 return 1;
50 } 50 }
51 51
52 int addInput( Bu::StrArray aArgs ) 52 int addInput( Bu::StrArray aArgs )
53 { 53 {
54 slInput.append( aArgs[0] ); 54 slInput.append( aArgs[0] );
55 return 0; 55 return 0;
56 } 56 }
57 57
58 Bu::String sClass; 58 Bu::String sClass;
59 Bu::String sOutBase; 59 Bu::String sOutBase;
60 Bu::String sOutDir; 60 Bu::String sOutDir;
61 Bu::StringList slInput; 61 Bu::StringList slInput;
62 Bu::StringList slFilter; 62 Bu::StringList slFilter;
63 Bu::String sSpecFile; 63 Bu::String sSpecFile;
64}; 64};
65 65
66int main( int argc, char *argv[] ) 66int main( int argc, char *argv[] )
67{ 67{
68 Options opt( argc, argv ); 68 Options opt( argc, argv );
69 69
70 if( !opt.sSpecFile.isEmpty() ) 70 if( !opt.sSpecFile.isEmpty() )
71 { 71 {
72 Bu::File fTaf( opt.sSpecFile, Bu::File::Read ); 72 Bu::File fTaf( opt.sSpecFile, Bu::File::Read );
73 Bu::TafReader rTaf( fTaf ); 73 Bu::TafReader rTaf( fTaf );
74 Bu::TafGroup *pRoot = rTaf.readGroup(); 74 Bu::TafGroup *pRoot = rTaf.readGroup();
75 75
76 if( pRoot == NULL || pRoot->getName() != "bin2cpp" ) 76 if( pRoot == NULL || pRoot->getName() != "bin2cpp" )
77 { 77 {
78 sio << "Specfied spec file does not appear to be a bin2cpp taf " 78 sio << "Specfied spec file does not appear to be a bin2cpp taf "
79 "specifications file." << sio.nl; 79 "specifications file." << sio.nl;
80 return 5; 80 return 5;
81 } 81 }
82 82
83 opt.sOutBase = opt.sClass = pRoot->getProperty("class"); 83 opt.sOutBase = opt.sClass = pRoot->getProperty("class");
84 if( pRoot->hasProperty("output") ) 84 if( pRoot->hasProperty("output") )
85 opt.sOutBase = pRoot->getProperty("output"); 85 opt.sOutBase = pRoot->getProperty("output");
86 opt.sOutDir = pRoot->getProperty("dir", ".") + "/"; 86 opt.sOutDir = pRoot->getProperty("dir", ".") + "/";
87 87
88 delete pRoot; 88 delete pRoot;
89 } 89 }
90 90
91 File fHdrOut( opt.sOutDir + opt.sOutBase + ".h", File::WriteNew ); 91 File fHdrOut( opt.sOutDir + opt.sOutBase + ".h", File::WriteNew );
92 File fSrcOut( opt.sOutDir + opt.sOutBase + ".cpp", File::WriteNew ); 92 File fSrcOut( opt.sOutDir + opt.sOutBase + ".cpp", File::WriteNew );
93 93
94 Bu::Hash<char, bool> hFilters; 94 Bu::Hash<char, bool> hFilters;
95 95
96 Formatter fHdr( fHdrOut ); 96 Formatter fHdr( fHdrOut );
97 Formatter fSrc( fSrcOut ); 97 Formatter fSrc( fSrcOut );
98 fHdr << "#ifndef BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl 98 fHdr << "#ifndef BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl
99 << "#define BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl << fHdr.nl 99 << "#define BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl << fHdr.nl
100 << "#include <bu/string.h>" << fHdr.nl 100 << "#include <bu/string.h>" << fHdr.nl
101 << "#include <bu/streamstack.h>" << fHdr.nl 101 << "#include <bu/streamstack.h>" << fHdr.nl
102 << fHdr.nl 102 << fHdr.nl
103 << "class " << opt.sClass << fHdr.nl 103 << "class " << opt.sClass << fHdr.nl
104 << "{" << fHdr.nl 104 << "{" << fHdr.nl
105 << "public:" << fHdr.nl 105 << "public:" << fHdr.nl
106 << "\tclass File { public: int iSize; const char *data; const char *flt; };" << fHdr.nl << fHdr.nl 106 << "\tclass File { public: int iSize; const char *data; const char *flt; };" << fHdr.nl << fHdr.nl
107 << "\tstatic const File &getFile( const Bu::String &sName );" << fHdr.nl 107 << "\tstatic const File &getFile( const Bu::String &sName );" << fHdr.nl
108 << "\tstatic Bu::StreamStack *open( const Bu::String &sName );" << fHdr.nl 108 << "\tstatic Bu::StreamStack *open( const Bu::String &sName );" << fHdr.nl
109 << "\tstatic Bu::StreamStack *openRaw( const Bu::String &sName );" << fHdr.nl 109 << "\tstatic Bu::StreamStack *openRaw( const Bu::String &sName );" << fHdr.nl
110 << "\tstatic Bu::String getString( const Bu::String &sName );" << fHdr.nl 110 << "\tstatic Bu::String getString( const Bu::String &sName );" << fHdr.nl
111 << "\tstatic Bu::String getStringRaw( const Bu::String &sName );" << fHdr.nl 111 << "\tstatic Bu::String getStringRaw( const Bu::String &sName );" << fHdr.nl
112 << fHdr.nl; 112 << fHdr.nl;
113 fHdr << "public:" << fHdr.nl 113 fHdr << "public:" << fHdr.nl
114 << "\tstatic const File aFile[];" << fHdr.nl 114 << "\tstatic const File aFile[];" << fHdr.nl
115 << "};" << fHdr.nl << fHdr.nl; 115 << "};" << fHdr.nl << fHdr.nl;
116 fHdr << "#endif"; 116 fHdr << "#endif";
117 117
118 fSrc << "#include \"" << opt.sOutBase << ".h\"" << fSrc.nl 118 fSrc << "#include \"" << opt.sOutBase << ".h\"" << fSrc.nl
119 << "#include <bu/deflate.h>" << fSrc.nl 119 << "#include <bu/deflate.h>" << fSrc.nl
120 << "#include <bu/bzip2.h>" << fSrc.nl 120 << "#include <bu/bzip2.h>" << fSrc.nl
121 << "#include <bu/base64.h>" << fSrc.nl 121 << "#include <bu/base64.h>" << fSrc.nl
122 << "#include <bu/lzma.h>" << fSrc.nl 122 << "#include <bu/lzma.h>" << fSrc.nl
123 << "#include <bu/hex.h>" << fSrc.nl 123 << "#include <bu/hex.h>" << fSrc.nl
124 << "#include <bu/strfilter.h>" << fSrc.nl 124 << "#include <bu/strfilter.h>" << fSrc.nl
125 << "#include <bu/staticmembuf.h>" << fSrc.nl << fSrc.nl 125 << "#include <bu/staticmembuf.h>" << fSrc.nl << fSrc.nl
126 << "const " << opt.sClass << "::File " << opt.sClass << "::aFile[] = {" << fSrc.nl; 126 << "const " << opt.sClass << "::File " << opt.sClass << "::aFile[] = {" << fSrc.nl;
127 127
128 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ ) 128 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ )
129 { 129 {
130 File fIn( *i, File::Read ); 130 File fIn( *i, File::Read );
131 Bu::String sDat; 131 Bu::String sDat;
132 char buf[1024]; 132 char buf[1024];
133 while( !fIn.isEos() ) 133 while( !fIn.isEos() )
134 { 134 {
135 sDat.append( buf, fIn.read( buf, 1024 ) ); 135 sDat.append( buf, fIn.read( buf, 1024 ) );
136 } 136 }
137 137
138 Bu::String sFltDesc; 138 Bu::String sFltDesc;
139 for( Bu::StringList::iterator f = opt.slFilter.begin(); f; f++ ) 139 for( Bu::StringList::iterator f = opt.slFilter.begin(); f; f++ )
140 { 140 {
141 if( *f == "deflate" ) 141 if( *f == "deflate" )
142 { 142 {
143 sDat = encodeStr<Deflate>( sDat ); 143 sDat = encodeStr<Deflate>( sDat );
144 sFltDesc.prepend("d"); 144 sFltDesc.prepend("d");
145 hFilters.insert('d', true ); 145 hFilters.insert('d', true );
146 } 146 }
147 else if( *f == "bzip2" ) 147 else if( *f == "bzip2" )
148 { 148 {
149 sDat = encodeStr<BZip2>( sDat ); 149 sDat = encodeStr<BZip2>( sDat );
150 sFltDesc.prepend("b"); 150 sFltDesc.prepend("b");
151 hFilters.insert('b', true ); 151 hFilters.insert('b', true );
152 } 152 }
153 else if( *f == "lzma" ) 153 else if( *f == "lzma" )
154 { 154 {
155 sDat = encodeStr<Lzma>( sDat ); 155 sDat = encodeStr<Lzma>( sDat );
156 sFltDesc.prepend("l"); 156 sFltDesc.prepend("l");
157 hFilters.insert('l', true ); 157 hFilters.insert('l', true );
158 } 158 }
159 else if( *f == "base64" ) 159 else if( *f == "base64" )
160 { 160 {
161 sDat = encodeStr<Base64>( sDat ); 161 sDat = encodeStr<Base64>( sDat );
162 sFltDesc.prepend("6"); 162 sFltDesc.prepend("6");
163 hFilters.insert('6', true ); 163 hFilters.insert('6', true );
164 } 164 }
165 else if( *f == "hex" ) 165 else if( *f == "hex" )
166 { 166 {
167 sDat = encodeStr<Hex>( sDat ); 167 sDat = encodeStr<Hex>( sDat );
168 sFltDesc.prepend("h"); 168 sFltDesc.prepend("h");
169 hFilters.insert('h', true ); 169 hFilters.insert('h', true );
170 } 170 }
171 else 171 else
172 { 172 {
173 sio << "No known filter named " << *f << sio.nl; 173 sio << "No known filter named " << *f << sio.nl;
174 return 1; 174 return 1;
175 } 175 }
176 } 176 }
177 177
178 fSrc << " {" << sDat.getSize() << ", \""; 178 fSrc << " {" << sDat.getSize() << ", \"";
179 179
180 for( Bu::String::iterator j = sDat.begin(); j; j++ ) 180 for( Bu::String::iterator j = sDat.begin(); j; j++ )
181 { 181 {
182 fSrc << "\\x" << Fmt::hex() << (unsigned char)*j; 182 fSrc << "\\x" << Fmt::hex() << (unsigned char)*j;
183 } 183 }
184 fSrc << "\", \"" << sFltDesc << "\"}," << fSrc.nl; 184 fSrc << "\", \"" << sFltDesc << "\"}," << fSrc.nl;
185 } 185 }
186 fSrc << "};" << fSrc.nl << fSrc.nl; 186 fSrc << "};" << fSrc.nl << fSrc.nl;
187 187
188 fSrc << "const " << opt.sClass << "::File &" << opt.sClass << "::getFile( const Bu::String &sName )" 188 fSrc << "const " << opt.sClass << "::File &" << opt.sClass << "::getFile( const Bu::String &sName )"
189 << fSrc.nl 189 << fSrc.nl
190 << "{" << fSrc.nl 190 << "{" << fSrc.nl
191 << "\tswitch( Bu::__calcHashCode( sName ) )" << fSrc.nl 191 << "\tswitch( Bu::__calcHashCode( sName ) )" << fSrc.nl
192 << "\t{" << fSrc.nl; 192 << "\t{" << fSrc.nl;
193 193
194 int idx = 0; 194 int idx = 0;
195 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ ) 195 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ )
196 { 196 {
197 fSrc << "\t\tcase " << Bu::__calcHashCode( *i ) << "UL:" << fSrc.nl 197 fSrc << "\t\tcase " << Bu::__calcHashCode( *i ) << "UL:" << fSrc.nl
198 << "\t\t\treturn aFile[" << idx << "];" << fSrc.nl; 198 << "\t\t\treturn aFile[" << idx << "];" << fSrc.nl;
199 idx++; 199 idx++;
200 } 200 }
201 fSrc << "\t}" << fSrc.nl 201 fSrc << "\t}" << fSrc.nl
202 << "\tthrow Bu::ExceptionBase(\"No file matching \\\"%s\\\" found.\", sName.getStr() );" << fSrc.nl 202 << "\tthrow Bu::ExceptionBase(\"No file matching \\\"%s\\\" found.\", sName.getStr() );" << fSrc.nl
203 << "}" << fSrc.nl << fSrc.nl; 203 << "}" << fSrc.nl << fSrc.nl;
204 204
205 fSrc << "Bu::StreamStack *" << opt.sClass << "::open( const Bu::String &sName )" << fSrc.nl 205 fSrc << "Bu::StreamStack *" << opt.sClass << "::open( const Bu::String &sName )" << fSrc.nl
206 << "{" << fSrc.nl 206 << "{" << fSrc.nl
207 << "\tconst File &f = getFile( sName );" << fSrc.nl 207 << "\tconst File &f = getFile( sName );" << fSrc.nl
208 << "\tBu::StreamStack *s = new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl; 208 << "\tBu::StreamStack *s = new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl;
209 209
210 if( !hFilters.isEmpty() ) 210 if( !hFilters.isEmpty() )
211 { 211 {
212 fSrc << "\tfor( const char *t = f.flt; *t; t++ )" << fSrc.nl 212 fSrc << "\tfor( const char *t = f.flt; *t; t++ )" << fSrc.nl
213 << "\t{" << fSrc.nl 213 << "\t{" << fSrc.nl
214 << "\t\tswitch( *t )" << fSrc.nl 214 << "\t\tswitch( *t )" << fSrc.nl
215 << "\t\t{" << fSrc.nl; 215 << "\t\t{" << fSrc.nl;
216 if( hFilters.has('d') ) 216 if( hFilters.has('d') )
217 fSrc << "\t\t\tcase 'd': s->pushFilter<Bu::Deflate>(); break;" << fSrc.nl; 217 fSrc << "\t\t\tcase 'd': s->pushFilter<Bu::Deflate>(); break;" << fSrc.nl;
218 if( hFilters.has('b') ) 218 if( hFilters.has('b') )
219 fSrc << "\t\t\tcase 'b': s->pushFilter<Bu::BZip2>(); break;" << fSrc.nl; 219 fSrc << "\t\t\tcase 'b': s->pushFilter<Bu::BZip2>(); break;" << fSrc.nl;
220 if( hFilters.has('l') ) 220 if( hFilters.has('l') )
221 fSrc << "\t\t\tcase 'l': s->pushFilter<Bu::Lzma>(); break;" << fSrc.nl; 221 fSrc << "\t\t\tcase 'l': s->pushFilter<Bu::Lzma>(); break;" << fSrc.nl;
222 if( hFilters.has('6') ) 222 if( hFilters.has('6') )
223 fSrc << "\t\t\tcase '6': s->pushFilter<Bu::Base64>(); break;" << fSrc.nl; 223 fSrc << "\t\t\tcase '6': s->pushFilter<Bu::Base64>(); break;" << fSrc.nl;
224 if( hFilters.has('h') ) 224 if( hFilters.has('h') )
225 fSrc << "\t\t\tcase 'h': s->pushFilter<Bu::Hex>(); break;" << fSrc.nl; 225 fSrc << "\t\t\tcase 'h': s->pushFilter<Bu::Hex>(); break;" << fSrc.nl;
226 fSrc << "\t\t}" << fSrc.nl 226 fSrc << "\t\t}" << fSrc.nl
227 << "\t}" << fSrc.nl; 227 << "\t}" << fSrc.nl;
228 } 228 }
229 fSrc << "\treturn s;" << fSrc.nl 229 fSrc << "\treturn s;" << fSrc.nl
230 << "}" << fSrc.nl << fSrc.nl; 230 << "}" << fSrc.nl << fSrc.nl;
231 231
232 fSrc << "Bu::StreamStack *" << opt.sClass << "::openRaw( const Bu::String &sName )" << fSrc.nl 232 fSrc << "Bu::StreamStack *" << opt.sClass << "::openRaw( const Bu::String &sName )" << fSrc.nl
233 << "{" << fSrc.nl 233 << "{" << fSrc.nl
234 << "\tconst File &f = getFile( sName );" << fSrc.nl 234 << "\tconst File &f = getFile( sName );" << fSrc.nl
235 << "\treturn new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl 235 << "\treturn new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl
236 << "}" << fSrc.nl << fSrc.nl; 236 << "}" << fSrc.nl << fSrc.nl;
237 237
238 fSrc << "Bu::String " << opt.sClass << "::getString( const Bu::String &sName )" << fSrc.nl 238 fSrc << "Bu::String " << opt.sClass << "::getString( const Bu::String &sName )" << fSrc.nl
239 << "{" << fSrc.nl 239 << "{" << fSrc.nl
240 << "\tBu::StreamStack *ss = open( sName );" << fSrc.nl 240 << "\tBu::StreamStack *ss = open( sName );" << fSrc.nl
241 << "\tBu::String s;" << fSrc.nl 241 << "\tBu::String s;" << fSrc.nl
242 << "\tchar buf[1024];" << fSrc.nl 242 << "\tchar buf[1024];" << fSrc.nl
243 << "\twhile( !ss->isEos() )" << fSrc.nl 243 << "\twhile( !ss->isEos() )" << fSrc.nl
244 << "\t{" << fSrc.nl 244 << "\t{" << fSrc.nl
245 << "\t\ts.append( buf, ss->read( buf, 1024 ) );" << fSrc.nl 245 << "\t\ts.append( buf, ss->read( buf, 1024 ) );" << fSrc.nl
246 << "\t}" << fSrc.nl 246 << "\t}" << fSrc.nl
247 << "\tdelete ss;" << fSrc.nl 247 << "\tdelete ss;" << fSrc.nl
248 << "\treturn s;" << fSrc.nl 248 << "\treturn s;" << fSrc.nl
249 << "}" << fSrc.nl << fSrc.nl; 249 << "}" << fSrc.nl << fSrc.nl;
250 250
251 fSrc << "Bu::String " << opt.sClass << "::getStringRaw( const Bu::String &sName )" << fSrc.nl 251 fSrc << "Bu::String " << opt.sClass << "::getStringRaw( const Bu::String &sName )" << fSrc.nl
252 << "{" << fSrc.nl 252 << "{" << fSrc.nl
253 << "\tconst File &f = getFile( sName );" << fSrc.nl 253 << "\tconst File &f = getFile( sName );" << fSrc.nl
254 << "\treturn Bu::String( f.data, f.iSize );" << fSrc.nl 254 << "\treturn Bu::String( f.data, f.iSize );" << fSrc.nl
255 << "}" << fSrc.nl << fSrc.nl; 255 << "}" << fSrc.nl << fSrc.nl;
256 256
257 return 0; 257 return 0;
258} 258}
259 259
diff --git a/src/tools/mkunit.cpp b/src/tools/mkunit.cpp
index d634feb..96deb6b 100644
--- a/src/tools/mkunit.cpp
+++ b/src/tools/mkunit.cpp
@@ -17,236 +17,236 @@ using namespace Bu;
17class Test 17class Test
18{ 18{
19public: 19public:
20 Test() : 20 Test() :
21 bExpectPass( true ) 21 bExpectPass( true )
22 { 22 {
23 } 23 }
24 24
25 Bu::String sName; 25 Bu::String sName;
26 bool bExpectPass; 26 bool bExpectPass;
27}; 27};
28typedef Bu::List<Test> TestList; 28typedef Bu::List<Test> TestList;
29 29
30class Suite 30class Suite
31{ 31{
32public: 32public:
33 Bu::String sName; 33 Bu::String sName;
34 TestList lTest; 34 TestList lTest;
35}; 35};
36//typedef Bu::List<Suite> SuiteList; 36//typedef Bu::List<Suite> SuiteList;
37 37
38enum TokType 38enum TokType
39{ 39{
40 tokFluff, 40 tokFluff,
41 tokSuite, 41 tokSuite,
42 tokTest, 42 tokTest,
43 tokChar, 43 tokChar,
44 tokBlock, 44 tokBlock,
45 tokEof 45 tokEof
46}; 46};
47 47
48Bu::Formatter &operator<<( Bu::Formatter &f, TokType t ) 48Bu::Formatter &operator<<( Bu::Formatter &f, TokType t )
49{ 49{
50 switch( t ) 50 switch( t )
51 { 51 {
52 case tokFluff: return f << "tokFluff"; 52 case tokFluff: return f << "tokFluff";
53 case tokSuite: return f << "tokSuite"; 53 case tokSuite: return f << "tokSuite";
54 case tokTest: return f << "tokTest"; 54 case tokTest: return f << "tokTest";
55 case tokChar: return f << "tokChar"; 55 case tokChar: return f << "tokChar";
56 case tokBlock: return f << "tokBlock"; 56 case tokBlock: return f << "tokBlock";
57 case tokEof: return f << "tokEof"; 57 case tokEof: return f << "tokEof";
58 } 58 }
59 59
60 return f; 60 return f;
61} 61}
62 62
63Bu::Formatter &operator<<( Bu::Formatter &f, const Test &t ) 63Bu::Formatter &operator<<( Bu::Formatter &f, const Test &t )
64{ 64{
65 return f << "{" << t.sName << ", bExpectPass=" << t.bExpectPass << "}"; 65 return f << "{" << t.sName << ", bExpectPass=" << t.bExpectPass << "}";
66} 66}
67 67
68Bu::Formatter &operator<<( Bu::Formatter &f, const Suite &s ) 68Bu::Formatter &operator<<( Bu::Formatter &f, const Suite &s )
69{ 69{
70 return f << "Suite[" << s.sName << "] = " << s.lTest << f.nl; 70 return f << "Suite[" << s.sName << "] = " << s.lTest << f.nl;
71} 71}
72 72
73class Parser 73class Parser
74{ 74{
75public: 75public:
76 Parser( const Bu::String &sFile ) : 76 Parser( const Bu::String &sFile ) :
77 sIn( sFile ), 77 sIn( sFile ),
78 fIn( sFile, File::Read ), 78 fIn( sFile, File::Read ),
79 bIn( fIn ), 79 bIn( fIn ),
80 cBuf( 0 ), 80 cBuf( 0 ),
81 bAvail( false ), 81 bAvail( false ),
82 eMode( mRoot ), 82 eMode( mRoot ),
83 iLine( 1 ), 83 iLine( 1 ),
84 iChar( 0 ), 84 iChar( 0 ),
85 iDepth( 0 ) 85 iDepth( 0 )
86 { 86 {
87 } 87 }
88 88
89 char nextChar() 89 char nextChar()
90 { 90 {
91 if( bAvail ) 91 if( bAvail )
92 return cBuf; 92 return cBuf;
93 93
94 if( bIn.read( &cBuf, 1 ) < 1 ) 94 if( bIn.read( &cBuf, 1 ) < 1 )
95 throw Bu::ExceptionBase("End of stream"); 95 throw Bu::ExceptionBase("End of stream");
96 bAvail = true; 96 bAvail = true;
97 97
98 if( cBuf == '\n' ) 98 if( cBuf == '\n' )
99 { 99 {
100 iLine++; 100 iLine++;
101 iChar = 0; 101 iChar = 0;
102 } 102 }
103 else 103 else
104 iChar++; 104 iChar++;
105 105
106 return cBuf; 106 return cBuf;
107 } 107 }
108 108
109 TokType nextToken( Variant &v, Bu::String &sWsOut, int &iLineStart, 109 TokType nextToken( Variant &v, Bu::String &sWsOut, int &iLineStart,
110 int &iCharStart ) 110 int &iCharStart )
111 { 111 {
112 Bu::String sTok, sWs; 112 Bu::String sTok, sWs;
113 113
114 char buf; 114 char buf;
115 try 115 try
116 { 116 {
117 buf = nextChar(); 117 buf = nextChar();
118 } 118 }
119 catch(...) 119 catch(...)
120 { 120 {
121 return tokEof; 121 return tokEof;
122 } 122 }
123 123
124 for(;;) 124 for(;;)
125 { 125 {
126 if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' ) 126 if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' )
127 { 127 {
128 sWs += buf; 128 sWs += buf;
129 bAvail = false; 129 bAvail = false;
130 } 130 }
131 else 131 else
132 break; 132 break;
133 133
134 try 134 try
135 { 135 {
136 buf = nextChar(); 136 buf = nextChar();
137 } 137 }
138 catch(...) 138 catch(...)
139 { 139 {
140 sWsOut = sWs; 140 sWsOut = sWs;
141 return tokEof; 141 return tokEof;
142 } 142 }
143 } 143 }
144 144
145 sWsOut = sWs; 145 sWsOut = sWs;
146 146
147 iLineStart = iLine; 147 iLineStart = iLine;
148 iCharStart = iChar; 148 iCharStart = iChar;
149 bool bInStr = false; 149 bool bInStr = false;
150 bool bDblStr; 150 bool bDblStr;
151 151
152 for(;;) 152 for(;;)
153 { 153 {
154 switch( eMode ) 154 switch( eMode )
155 { 155 {
156 case mRoot: 156 case mRoot:
157 if( buf == ' ' || buf == '\t' || buf == '\n' 157 if( buf == ' ' || buf == '\t' || buf == '\n'
158 || buf == '\r' ) 158 || buf == '\r' )
159 { 159 {
160 if( sTok == "suite" ) 160 if( sTok == "suite" )
161 return tokSuite; 161 return tokSuite;
162 else 162 else
163 { 163 {
164 v = sTok; 164 v = sTok;
165 return tokFluff; 165 return tokFluff;
166 } 166 }
167 } 167 }
168 else if( buf == '(' || buf == ')' || buf == '{' 168 else if( buf == '(' || buf == ')' || buf == '{'
169 || buf == '}' || buf == ';' ) 169 || buf == '}' || buf == ';' )
170 { 170 {
171 if( sTok.getSize() == 0 ) 171 if( sTok.getSize() == 0 )
172 { 172 {
173 bAvail = false; 173 bAvail = false;
174 v = buf; 174 v = buf;
175 return tokChar; 175 return tokChar;
176 } 176 }
177 else 177 else
178 { 178 {
179 v = sTok; 179 v = sTok;
180 return tokFluff; 180 return tokFluff;
181 } 181 }
182 } 182 }
183 else 183 else
184 { 184 {
185 sTok += buf; 185 sTok += buf;
186 bAvail = false; 186 bAvail = false;
187 } 187 }
188 break; 188 break;
189 189
190 case mSuite: 190 case mSuite:
191 if( buf == ' ' || buf == '\t' || buf == '\n' 191 if( buf == ' ' || buf == '\t' || buf == '\n'
192 || buf == '\r' ) 192 || buf == '\r' )
193 { 193 {
194 if( sTok == "test" ) 194 if( sTok == "test" )
195 return tokTest; 195 return tokTest;
196 else 196 else
197 { 197 {
198 v = sTok; 198 v = sTok;
199 return tokFluff; 199 return tokFluff;
200 } 200 }
201 } 201 }
202 else if( buf == '(' || buf == ')' 202 else if( buf == '(' || buf == ')'
203 || buf == '}' || buf == ';' ) 203 || buf == '}' || buf == ';' )
204 { 204 {
205 if( sTok.getSize() == 0 ) 205 if( sTok.getSize() == 0 )
206 { 206 {
207 bAvail = false; 207 bAvail = false;
208 v = buf; 208 v = buf;
209 return tokChar; 209 return tokChar;
210 } 210 }
211 else 211 else
212 { 212 {
213 v = sTok; 213 v = sTok;
214 return tokFluff; 214 return tokFluff;
215 } 215 }
216 } 216 }
217 else if( buf == '{' ) 217 else if( buf == '{' )
218 { 218 {
219 if( sTok.getSize() > 0 ) 219 if( sTok.getSize() > 0 )
220 { 220 {
221 v = sTok; 221 v = sTok;
222 return tokFluff; 222 return tokFluff;
223 } 223 }
224 else 224 else
225 { 225 {
226 sTok += buf; 226 sTok += buf;
227 bAvail = false; 227 bAvail = false;
228 eMode = mBlock; 228 eMode = mBlock;
229 iDepth = 1; 229 iDepth = 1;
230 } 230 }
231 } 231 }
232 else 232 else
233 { 233 {
234 sTok += buf; 234 sTok += buf;
235 bAvail = false; 235 bAvail = false;
236 } 236 }
237 break; 237 break;
238 238
239 case mBlock: 239 case mBlock:
240 if( bInStr ) 240 if( bInStr )
241 { 241 {
242 if( buf == '\\' ) 242 if( buf == '\\' )
243 { 243 {
244 sTok += buf; 244 sTok += buf;
245 bAvail = false; 245 bAvail = false;
246 sTok += nextChar(); 246 sTok += nextChar();
247 bAvail = false; 247 bAvail = false;
248 } 248 }
249 else if( bDblStr == true && buf == '\"' ) 249 else if( bDblStr == true && buf == '\"' )
250 { 250 {
251 sTok += buf; 251 sTok += buf;
252 bAvail = false; 252 bAvail = false;
@@ -267,295 +267,295 @@ public:
267 else 267 else
268 { 268 {
269 if( buf == '\"' ) 269 if( buf == '\"' )
270 { 270 {
271 bInStr = true; 271 bInStr = true;
272 bDblStr = true; 272 bDblStr = true;
273 sTok += buf; 273 sTok += buf;
274 bAvail = false; 274 bAvail = false;
275 } 275 }
276 else if( buf == '\'' ) 276 else if( buf == '\'' )
277 { 277 {
278 bInStr = true; 278 bInStr = true;
279 bDblStr = false; 279 bDblStr = false;
280 sTok += buf; 280 sTok += buf;
281 bAvail = false; 281 bAvail = false;
282 } 282 }
283 else if( buf == '}' ) 283 else if( buf == '}' )
284 { 284 {
285 sTok += buf; 285 sTok += buf;
286 bAvail = false; 286 bAvail = false;
287 iDepth--; 287 iDepth--;
288 if( iDepth == 0 ) 288 if( iDepth == 0 )
289 { 289 {
290 v = sTok; 290 v = sTok;
291 eMode = mSuite; 291 eMode = mSuite;
292 return tokBlock; 292 return tokBlock;
293 } 293 }
294 } 294 }
295 else if( buf == '{' ) 295 else if( buf == '{' )
296 { 296 {
297 sTok += buf; 297 sTok += buf;
298 bAvail = false; 298 bAvail = false;
299 iDepth++; 299 iDepth++;
300 } 300 }
301 else 301 else
302 { 302 {
303 sTok += buf; 303 sTok += buf;
304 bAvail = false; 304 bAvail = false;
305 } 305 }
306 } 306 }
307 break; 307 break;
308 } 308 }
309 309
310 buf = nextChar(); 310 buf = nextChar();
311 } 311 }
312 } 312 }
313 313
314 void firstPass() 314 void firstPass()
315 { 315 {
316 Variant v; 316 Variant v;
317 Bu::String sWs; 317 Bu::String sWs;
318 int iL, iC; 318 int iL, iC;
319 for(;;) 319 for(;;)
320 { 320 {
321 TokType t = nextToken( v, sWs, iL, iC ); 321 TokType t = nextToken( v, sWs, iL, iC );
322 if( t == tokEof ) 322 if( t == tokEof )
323 return; 323 return;
324 switch( eMode ) 324 switch( eMode )
325 { 325 {
326 case mRoot: 326 case mRoot:
327 if( t == tokSuite ) 327 if( t == tokSuite )
328 { 328 {
329 if( nextToken( v, sWs, iL, iC ) != tokFluff ) 329 if( nextToken( v, sWs, iL, iC ) != tokFluff )
330 throw Bu::ExceptionBase("%d:%d: Expected string " 330 throw Bu::ExceptionBase("%d:%d: Expected string "
331 "following suite.", iL, iC ); 331 "following suite.", iL, iC );
332 s.sName = v.get<Bu::String>(); 332 s.sName = v.get<Bu::String>();
333 if( nextToken( v, sWs, iL, iC ) != tokChar || 333 if( nextToken( v, sWs, iL, iC ) != tokChar ||
334 v.get<char>() != '{' ) 334 v.get<char>() != '{' )
335 throw Bu::ExceptionBase("%d:%d: Expected {, got " 335 throw Bu::ExceptionBase("%d:%d: Expected {, got "
336 "'%s'", iL, iC, v.toString().getStr() ); 336 "'%s'", iL, iC, v.toString().getStr() );
337 eMode = mSuite; 337 eMode = mSuite;
338 } 338 }
339 break; 339 break;
340 340
341 case mSuite: 341 case mSuite:
342 switch( t ) 342 switch( t )
343 { 343 {
344 case tokFluff: 344 case tokFluff:
345 break; 345 break;
346 346
347 case tokBlock: 347 case tokBlock:
348 break; 348 break;
349 349
350 case tokTest: 350 case tokTest:
351 { 351 {
352 if( nextToken( v, sWs, iL, iC ) != tokFluff ) 352 if( nextToken( v, sWs, iL, iC ) != tokFluff )
353 throw Bu::ExceptionBase("%d:%d: Expected " 353 throw Bu::ExceptionBase("%d:%d: Expected "
354 "string following test.", iL, iC ); 354 "string following test.", iL, iC );
355 Test t; 355 Test t;
356 t.sName = v.get<Bu::String>(); 356 t.sName = v.get<Bu::String>();
357 if( nextToken( v, sWs, iL, iC ) != tokBlock ) 357 if( nextToken( v, sWs, iL, iC ) != tokBlock )
358 throw Bu::ExceptionBase("%d:%d: Expected " 358 throw Bu::ExceptionBase("%d:%d: Expected "
359 "{...} block.", 359 "{...} block.",
360 iL, iC ); 360 iL, iC );
361 s.lTest.append( t ); 361 s.lTest.append( t );
362 } 362 }
363 break; 363 break;
364 364
365 case tokChar: 365 case tokChar:
366 if( v.get<char>() == '}' ) 366 if( v.get<char>() == '}' )
367 { 367 {
368 eMode = mRoot; 368 eMode = mRoot;
369 } 369 }
370 else 370 else
371 { 371 {
372 } 372 }
373 break; 373 break;
374 374
375 default: 375 default:
376 sio << iL << ":" << iC << ": Unexpected " 376 sio << iL << ":" << iC << ": Unexpected "
377 << t << " found." << sio.nl; 377 << t << " found." << sio.nl;
378 return; 378 return;
379 break; 379 break;
380 } 380 }
381 break; 381 break;
382 382
383 default: 383 default:
384 sio << "???" << sio.nl; 384 sio << "???" << sio.nl;
385 break; 385 break;
386 } 386 }
387 } 387 }
388 } 388 }
389 389
390 void secondPass( const Bu::String &sOut ) 390 void secondPass( const Bu::String &sOut )
391 { 391 {
392 File fOut( sOut, File::WriteNew ); 392 File fOut( sOut, File::WriteNew );
393 Formatter f( fOut ); 393 Formatter f( fOut );
394 fIn.setPos( 0 ); 394 fIn.setPos( 0 );
395 bIn.stop(); 395 bIn.stop();
396 bIn.start(); 396 bIn.start();
397 bAvail = false; 397 bAvail = false;
398 eMode = mRoot; 398 eMode = mRoot;
399 iLine = 1; 399 iLine = 1;
400 iChar = 0; 400 iChar = 0;
401 bool bHasIncluded = false; 401 bool bHasIncluded = false;
402 402
403 Bu::String sWs; 403 Bu::String sWs;
404 Variant v; 404 Variant v;
405 int iL, iC; 405 int iL, iC;
406 for(;;) 406 for(;;)
407 { 407 {
408 TokType t = nextToken( v, sWs, iL, iC ); 408 TokType t = nextToken( v, sWs, iL, iC );
409 switch( eMode ) 409 switch( eMode )
410 { 410 {
411 case mRoot: 411 case mRoot:
412 if( t == tokSuite ) 412 if( t == tokSuite )
413 { 413 {
414 fOut.write( sWs ); 414 fOut.write( sWs );
415 if( nextToken( v, sWs, iL, iC ) != tokFluff ) 415 if( nextToken( v, sWs, iL, iC ) != tokFluff )
416 throw Bu::ExceptionBase("%d:%d: Expected string " 416 throw Bu::ExceptionBase("%d:%d: Expected string "
417 "following suite.", iL, iC ); 417 "following suite.", iL, iC );
418 s.sName = v.get<Bu::String>(); 418 s.sName = v.get<Bu::String>();
419 if( nextToken( v, sWs, iL, iC ) != tokChar || 419 if( nextToken( v, sWs, iL, iC ) != tokChar ||
420 v.get<char>() != '{' ) 420 v.get<char>() != '{' )
421 throw Bu::ExceptionBase("%d:%d: Expected {", 421 throw Bu::ExceptionBase("%d:%d: Expected {",
422 iL, iC ); 422 iL, iC );
423 eMode = mSuite; 423 eMode = mSuite;
424 424
425 if( bHasIncluded == false ) 425 if( bHasIncluded == false )
426 { 426 {
427 fOut.write("#include <bu/unitsuite.h>\n"); 427 fOut.write("#include <bu/unitsuite.h>\n");
428 bHasIncluded = true; 428 bHasIncluded = true;
429 } 429 }
430 430
431 Bu::String sClass = "_UnitSuite_" + s.sName; 431 Bu::String sClass = "_UnitSuite_" + s.sName;
432 f << "class " << sClass 432 f << "class " << sClass
433 << " : public Bu::UnitSuite" << f.nl 433 << " : public Bu::UnitSuite" << f.nl
434 << "{" << f.nl << "public:" << f.nl 434 << "{" << f.nl << "public:" << f.nl
435 << "\t" << sClass << "()" << f.nl 435 << "\t" << sClass << "()" << f.nl
436 << "\t{" << f.nl 436 << "\t{" << f.nl
437 << "\t\tsetName(\"" << s.sName << "\");" << f.nl; 437 << "\t\tsetName(\"" << s.sName << "\");" << f.nl;
438 for( TestList::iterator i = s.lTest.begin(); i; i++ ) 438 for( TestList::iterator i = s.lTest.begin(); i; i++ )
439 { 439 {
440 f << "\t\tadd( static_cast<Bu::UnitSuite::Test>(" 440 f << "\t\tadd( static_cast<Bu::UnitSuite::Test>("
441 "&" << sClass << "::" << (*i).sName << "), \"" 441 "&" << sClass << "::" << (*i).sName << "), \""
442 << (*i).sName << "\", Bu::UnitSuite::" 442 << (*i).sName << "\", Bu::UnitSuite::"
443 "expectPass );" << f.nl; 443 "expectPass );" << f.nl;
444 } 444 }
445 f << "\t}" << f.nl << f.nl 445 f << "\t}" << f.nl << f.nl
446 << "\tvirtual ~" << sClass << "() { }" << f.nl 446 << "\tvirtual ~" << sClass << "() { }" << f.nl
447 << f.nl; 447 << f.nl;
448 } 448 }
449 else if( t == tokEof ) 449 else if( t == tokEof )
450 { 450 {
451 Bu::String sClass = "_UnitSuite_" + s.sName; 451 Bu::String sClass = "_UnitSuite_" + s.sName;
452 f << sWs << f.nl << "int main( int argc, char *argv[] )" 452 f << sWs << f.nl << "int main( int argc, char *argv[] )"
453 << f.nl << "{" << f.nl << "\treturn " << sClass 453 << f.nl << "{" << f.nl << "\treturn " << sClass
454 << "().run( argc, argv );" << f.nl << "}" << f.nl; 454 << "().run( argc, argv );" << f.nl << "}" << f.nl;
455 } 455 }
456 else 456 else
457 { 457 {
458 fOut.write( sWs ); 458 fOut.write( sWs );
459 f << v; 459 f << v;
460 } 460 }
461 break; 461 break;
462 462
463 case mSuite: 463 case mSuite:
464 switch( t ) 464 switch( t )
465 { 465 {
466 case tokFluff: 466 case tokFluff:
467 fOut.write( sWs ); 467 fOut.write( sWs );
468 fOut.write( v.get<Bu::String>() ); 468 fOut.write( v.get<Bu::String>() );
469 break; 469 break;
470 470
471 case tokTest: 471 case tokTest:
472 { 472 {
473 fOut.write( sWs ); 473 fOut.write( sWs );
474 if( nextToken( v, sWs, iL, iC ) != tokFluff ) 474 if( nextToken( v, sWs, iL, iC ) != tokFluff )
475 throw Bu::ExceptionBase("%d:%d: Expected " 475 throw Bu::ExceptionBase("%d:%d: Expected "
476 "string following test.", iL, iC ); 476 "string following test.", iL, iC );
477 Test t; 477 Test t;
478 t.sName = v.get<Bu::String>(); 478 t.sName = v.get<Bu::String>();
479 if( nextToken( v, sWs, iL, iC ) != tokBlock ) 479 if( nextToken( v, sWs, iL, iC ) != tokBlock )
480 throw Bu::ExceptionBase("%d:%d: Expected " 480 throw Bu::ExceptionBase("%d:%d: Expected "
481 "{...} block.", 481 "{...} block.",
482 iL, iC ); 482 iL, iC );
483 483
484 f << "\tvoid " << t.sName << "()" 484 f << "\tvoid " << t.sName << "()"
485 << f.nl << "#line " << iL 485 << f.nl << "#line " << iL
486 << " \"" << sIn << "\"" << f.nl 486 << " \"" << sIn << "\"" << f.nl
487 << v << f.nl; 487 << v << f.nl;
488 } 488 }
489 break; 489 break;
490 490
491 case tokChar: 491 case tokChar:
492 if( v.get<char>() == '}' ) 492 if( v.get<char>() == '}' )
493 { 493 {
494 f << "};" << f.nl << f.nl; 494 f << "};" << f.nl << f.nl;
495 eMode = mRoot; 495 eMode = mRoot;
496 } 496 }
497 else 497 else
498 { 498 {
499 char buf = v.get<char>(); 499 char buf = v.get<char>();
500 fOut.write( sWs ); 500 fOut.write( sWs );
501 fOut.write( &buf, 1 ); 501 fOut.write( &buf, 1 );
502 } 502 }
503 break; 503 break;
504 504
505 case tokBlock: 505 case tokBlock:
506 fOut.write( sWs ); 506 fOut.write( sWs );
507 f << f.nl << "#line " << iL << " \"" << sIn 507 f << f.nl << "#line " << iL << " \"" << sIn
508 << "\"" << f.nl; 508 << "\"" << f.nl;
509 fOut.write( v.get<Bu::String>() ); 509 fOut.write( v.get<Bu::String>() );
510 510
511 break; 511 break;
512 512
513 default: 513 default:
514 sio << iL << ":" << iC << ": Unexpected " 514 sio << iL << ":" << iC << ": Unexpected "
515 << t << " found." << sio.nl; 515 << t << " found." << sio.nl;
516 return; 516 return;
517 break; 517 break;
518 } 518 }
519 break; 519 break;
520 520
521 default: 521 default:
522 sio << "???" << sio.nl; 522 sio << "???" << sio.nl;
523 break; 523 break;
524 } 524 }
525 if( t == tokEof ) 525 if( t == tokEof )
526 return; 526 return;
527 } 527 }
528 } 528 }
529 529
530private: 530private:
531 Bu::String sIn; 531 Bu::String sIn;
532 File fIn; 532 File fIn;
533 Buffer bIn; 533 Buffer bIn;
534 char cBuf; 534 char cBuf;
535 bool bAvail; 535 bool bAvail;
536 enum Mode 536 enum Mode
537 { 537 {
538 mRoot, 538 mRoot,
539 mSuite, 539 mSuite,
540 mBlock 540 mBlock
541 }; 541 };
542 Mode eMode; 542 Mode eMode;
543 int iLine, iChar; 543 int iLine, iChar;
544 int iDepth; 544 int iDepth;
545 Suite s; 545 Suite s;
546}; 546};
547 547
548int main( int argc, char *argv[] ) 548int main( int argc, char *argv[] )
549{ 549{
550 if( argc < 3 ) 550 if( argc < 3 )
551 { 551 {
552 sio << "Too few parameters." << sio.nl; 552 sio << "Too few parameters." << sio.nl;
553 return 0; 553 return 0;
554 } 554 }
555 Parser p( argv[1] ); 555 Parser p( argv[1] );
556 556
557 p.firstPass(); 557 p.firstPass();
558 558
559 p.secondPass( argv[2] ); 559 p.secondPass( argv[2] );
560} 560}
561 561
diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp
index 7cab628..8a288b0 100644
--- a/src/tools/myriad.cpp
+++ b/src/tools/myriad.cpp
@@ -17,237 +17,237 @@ using namespace Bu;
17 17
18enum Mode 18enum Mode
19{ 19{
20 modeCreate, 20 modeCreate,
21 modeInfo, 21 modeInfo,
22 modeStreamNew, 22 modeStreamNew,
23 modeStreamDump, 23 modeStreamDump,
24 modeStreamPut, 24 modeStreamPut,
25 modeStreamGet, 25 modeStreamGet,
26 26
27 modeNone 27 modeNone
28}; 28};
29 29
30class Options : public OptParser 30class Options : public OptParser
31{ 31{
32public: 32public:
33 Options( int argc, char *argv[] ) : 33 Options( int argc, char *argv[] ) :
34 eMode( modeNone ), 34 eMode( modeNone ),
35 iBlockSize( 64 ), 35 iBlockSize( 64 ),
36 iPreallocate( 0 ), 36 iPreallocate( 0 ),
37 iStream( 0 ) 37 iStream( 0 )
38 { 38 {
39 addHelpBanner("Mode of operation:"); 39 addHelpBanner("Mode of operation:");
40 addOption( eMode, 'c', "create", 40 addOption( eMode, 'c', "create",
41 "Create a new Myriad file." ); 41 "Create a new Myriad file." );
42 addOption( eMode, 'i', "info", 42 addOption( eMode, 'i', "info",
43 "Display some info about a Myriad file." ); 43 "Display some info about a Myriad file." );
44 addOption( eMode, 'n', "new", 44 addOption( eMode, 'n', "new",
45 "Create a new sub-stream in a Myriad file."); 45 "Create a new sub-stream in a Myriad file.");
46 addOption( eMode, 'd', "dump", 46 addOption( eMode, 'd', "dump",
47 "Display a hexdump of a stream from a Myriad file."); 47 "Display a hexdump of a stream from a Myriad file.");
48 addOption( eMode, "get", 48 addOption( eMode, "get",
49 "Get a file out of a Myriad stream (use --dst)."); 49 "Get a file out of a Myriad stream (use --dst).");
50 addOption( eMode, "put", 50 addOption( eMode, "put",
51 "Put a file into a Myriad stream (usr --src)."); 51 "Put a file into a Myriad stream (usr --src).");
52 addHelpOption(); 52 addHelpOption();
53 53
54 addHelpBanner("\nGeneral options:"); 54 addHelpBanner("\nGeneral options:");
55 addOption( iBlockSize, 'b', "block-size", "Set the block size." ); 55 addOption( iBlockSize, 'b', "block-size", "Set the block size." );
56 addOption( iPreallocate, 'p', "preallocate", 56 addOption( iPreallocate, 'p', "preallocate",
57 "Number of blocks to preallocate." ); 57 "Number of blocks to preallocate." );
58 addOption( sFile, 'f', "file", "Set the Myriad filename." ); 58 addOption( sFile, 'f', "file", "Set the Myriad filename." );
59 addOption( iStream, 's', "stream", "Substream to work with."); 59 addOption( iStream, 's', "stream", "Substream to work with.");
60 addOption( sSrc, "src", "Source file for copying into a Myriad file."); 60 addOption( sSrc, "src", "Source file for copying into a Myriad file.");
61 addOption( sDst, "dst", 61 addOption( sDst, "dst",
62 "Destination file for copying out of a Myriad file."); 62 "Destination file for copying out of a Myriad file.");
63 63
64 setOverride( "create", modeCreate ); 64 setOverride( "create", modeCreate );
65 setOverride( "info", modeInfo ); 65 setOverride( "info", modeInfo );
66 setOverride( "new", modeStreamNew ); 66 setOverride( "new", modeStreamNew );
67 setOverride( "dump", modeStreamDump ); 67 setOverride( "dump", modeStreamDump );
68 setOverride( "put", modeStreamPut ); 68 setOverride( "put", modeStreamPut );
69 setOverride( "get", modeStreamGet ); 69 setOverride( "get", modeStreamGet );
70 70
71 parse( argc, argv ); 71 parse( argc, argv );
72 } 72 }
73 73
74 Mode eMode; 74 Mode eMode;
75 int iBlockSize; 75 int iBlockSize;
76 int iPreallocate; 76 int iPreallocate;
77 int iStream; 77 int iStream;
78 Bu::String sFile; 78 Bu::String sFile;
79 Bu::String sSrc; 79 Bu::String sSrc;
80 Bu::String sDst; 80 Bu::String sDst;
81}; 81};
82 82
83Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ ) 83Bu::Formatter &operator>>( Bu::Formatter &f, Mode & /*e*/ )
84{ 84{
85 sio << "Uh oh, the formatter was called..." << sio.nl; 85 sio << "Uh oh, the formatter was called..." << sio.nl;
86 return f; 86 return f;
87} 87}
88 88
89int main( int argc, char *argv[] ) 89int main( int argc, char *argv[] )
90{ 90{
91 Options opts( argc, argv ); 91 Options opts( argc, argv );
92 92
93 switch( opts.eMode ) 93 switch( opts.eMode )
94 { 94 {
95 case modeCreate: 95 case modeCreate:
96 if( !opts.sFile.isSet() ) 96 if( !opts.sFile.isSet() )
97 { 97 {
98 sio << "Please specify a file to create." << sio.nl; 98 sio << "Please specify a file to create." << sio.nl;
99 return 0; 99 return 0;
100 } 100 }
101 else 101 else
102 { 102 {
103 File fOut( opts.sFile, File::WriteNew|File::Read ); 103 File fOut( opts.sFile, File::WriteNew|File::Read );
104 Myriad m( fOut, opts.iBlockSize, opts.iPreallocate ); 104 Myriad m( fOut, opts.iBlockSize, opts.iPreallocate );
105 } 105 }
106 break; 106 break;
107 107
108 case modeInfo: 108 case modeInfo:
109 if( !opts.sFile.isSet() ) 109 if( !opts.sFile.isSet() )
110 { 110 {
111 sio << "Please specify a file to display info about." << sio.nl; 111 sio << "Please specify a file to display info about." << sio.nl;
112 return 0; 112 return 0;
113 } 113 }
114 else 114 else
115 { 115 {
116 File fIn( opts.sFile, File::Read ); 116 File fIn( opts.sFile, File::Read );
117 Myriad m( fIn ); 117 Myriad m( fIn );
118 sio << "Myriad info:" << sio.nl 118 sio << "Myriad info:" << sio.nl
119 << " Block size: " << m.getBlockSize() << sio.nl 119 << " Block size: " << m.getBlockSize() << sio.nl
120 << " Block count: " << m.getNumBlocks() << sio.nl 120 << " Block count: " << m.getNumBlocks() << sio.nl
121 << " Blocks used: " << m.getNumUsedBlocks() << " (" 121 << " Blocks used: " << m.getNumUsedBlocks() << " ("
122 << m.getNumUsedBlocks()*100/m.getNumBlocks() << "%)" 122 << m.getNumUsedBlocks()*100/m.getNumBlocks() << "%)"
123 << sio.nl 123 << sio.nl
124 << " Stream count: " << m.getNumStreams() << sio.nl 124 << " Stream count: " << m.getNumStreams() << sio.nl
125 << " Used space: " << m.getTotalUsedBytes() << sio.nl 125 << " Used space: " << m.getTotalUsedBytes() << sio.nl
126 << " Unused space: " << m.getTotalUnusedBytes() << sio.nl 126 << " Unused space: " << m.getTotalUnusedBytes() << sio.nl
127 << " % of files: " << (double)(m.getNumBlocks()*m.getBlockSize())/(double)(m.getTotalUsedBytes() + m.getTotalUnusedBytes( 4096 ))*100.0 << sio.nl; 127 << " % of files: " << (double)(m.getNumBlocks()*m.getBlockSize())/(double)(m.getTotalUsedBytes() + m.getTotalUnusedBytes( 4096 ))*100.0 << sio.nl;
128/* Bu::Array<int> aStreams = m.getStreamIds(); 128/* Bu::Array<int> aStreams = m.getStreamIds();
129 sio << " Stream info:" << sio.nl; 129 sio << " Stream info:" << sio.nl;
130 for( Bu::Array<int>::iterator i = aStreams.begin(); i; i++ ) 130 for( Bu::Array<int>::iterator i = aStreams.begin(); i; i++ )
131 { 131 {
132 sio << " " << Fmt(4) << *i << ") " 132 sio << " " << Fmt(4) << *i << ") "
133 << m.getStreamSize( *i ) << "b" << sio.nl; 133 << m.getStreamSize( *i ) << "b" << sio.nl;
134 } */ 134 } */
135 } 135 }
136 break; 136 break;
137 137
138 case modeStreamNew: 138 case modeStreamNew:
139 if( !opts.sFile.isSet() ) 139 if( !opts.sFile.isSet() )
140 { 140 {
141 sio << "Please specify a file manipulate." << sio.nl; 141 sio << "Please specify a file manipulate." << sio.nl;
142 return 0; 142 return 0;
143 } 143 }
144 else 144 else
145 { 145 {
146 File fOut( opts.sFile, File::Write|File::Read ); 146 File fOut( opts.sFile, File::Write|File::Read );
147 Myriad m( fOut ); 147 Myriad m( fOut );
148 m.createStream( opts.iPreallocate ); 148 m.createStream( opts.iPreallocate );
149 } 149 }
150 break; 150 break;
151 151
152 case modeStreamDump: 152 case modeStreamDump:
153 if( !opts.sFile.isSet() ) 153 if( !opts.sFile.isSet() )
154 { 154 {
155 sio << "Please specify a file to manipulate." << sio.nl; 155 sio << "Please specify a file to manipulate." << sio.nl;
156 return 0; 156 return 0;
157 } 157 }
158 else 158 else
159 { 159 {
160 File fOut( opts.sFile, File::Read ); 160 File fOut( opts.sFile, File::Read );
161 Myriad m( fOut ); 161 Myriad m( fOut );
162 MyriadStream s = m.openStream( opts.iStream ); 162 MyriadStream s = m.openStream( opts.iStream );
163 sio << "Stream " << opts.iStream << ":" << sio.nl; 163 sio << "Stream " << opts.iStream << ":" << sio.nl;
164 char buf[8]; 164 char buf[8];
165 int iPos = 0; 165 int iPos = 0;
166 while( !s.isEos() ) 166 while( !s.isEos() )
167 { 167 {
168 size_t sAmnt = s.read( buf, 8 ); 168 size_t sAmnt = s.read( buf, 8 );
169 sio << Fmt(5) << iPos << ": "; 169 sio << Fmt(5) << iPos << ": ";
170 iPos += sAmnt; 170 iPos += sAmnt;
171 for( size_t j = 0; j < sAmnt; j++ ) 171 for( size_t j = 0; j < sAmnt; j++ )
172 { 172 {
173 sio << Fmt::hex(2) << (int)((unsigned char)buf[j]) 173 sio << Fmt::hex(2) << (int)((unsigned char)buf[j])
174 << " "; 174 << " ";
175 } 175 }
176 for( size_t j = sAmnt; j < 8; j++ ) 176 for( size_t j = sAmnt; j < 8; j++ )
177 { 177 {
178 sio << "-- "; 178 sio << "-- ";
179 } 179 }
180 sio << "| "; 180 sio << "| ";
181 for( size_t j = 0; j < sAmnt; j++ ) 181 for( size_t j = 0; j < sAmnt; j++ )
182 { 182 {
183 if( buf[j] >= 32 && buf[j] <= 126 ) 183 if( buf[j] >= 32 && buf[j] <= 126 )
184 sio << buf[j] << " "; 184 sio << buf[j] << " ";
185 else 185 else
186 sio << " "; 186 sio << " ";
187 } 187 }
188 sio << sio.nl; 188 sio << sio.nl;
189 } 189 }
190 sio << "Position: " << s.tell() << ", isEos()=" << s.isEos() 190 sio << "Position: " << s.tell() << ", isEos()=" << s.isEos()
191 << sio.nl; 191 << sio.nl;
192 } 192 }
193 break; 193 break;
194 194
195 case modeStreamPut: 195 case modeStreamPut:
196 if( !opts.sFile.isSet() ) 196 if( !opts.sFile.isSet() )
197 { 197 {
198 sio << "Please specify a file manipulate." << sio.nl; 198 sio << "Please specify a file manipulate." << sio.nl;
199 return 0; 199 return 0;
200 } 200 }
201 else if( !opts.sSrc.isSet() ) 201 else if( !opts.sSrc.isSet() )
202 { 202 {
203 sio << "Please specify a source file to read." << sio.nl; 203 sio << "Please specify a source file to read." << sio.nl;
204 } 204 }
205 else 205 else
206 { 206 {
207 File fOut( opts.sFile, File::Write|File::Read ); 207 File fOut( opts.sFile, File::Write|File::Read );
208 Myriad m( fOut ); 208 Myriad m( fOut );
209 MyriadStream sOut = m.openStream( 209 MyriadStream sOut = m.openStream(
210 m.createStream( opts.iPreallocate ) 210 m.createStream( opts.iPreallocate )
211 ); 211 );
212 File fIn( opts.sSrc, File::Read ); 212 File fIn( opts.sSrc, File::Read );
213 char buf[1024]; 213 char buf[1024];
214 while( !fIn.isEos() ) 214 while( !fIn.isEos() )
215 { 215 {
216 sOut.write( buf, fIn.read( buf, 1024 ) ); 216 sOut.write( buf, fIn.read( buf, 1024 ) );
217 } 217 }
218 } 218 }
219 break; 219 break;
220 220
221 case modeStreamGet: 221 case modeStreamGet:
222 if( !opts.sFile.isSet() ) 222 if( !opts.sFile.isSet() )
223 { 223 {
224 sio << "Please specify a file manipulate." << sio.nl; 224 sio << "Please specify a file manipulate." << sio.nl;
225 return 0; 225 return 0;
226 } 226 }
227 else if( !opts.sDst.isSet() ) 227 else if( !opts.sDst.isSet() )
228 { 228 {
229 sio << "Please specify a destination file to write." << sio.nl; 229 sio << "Please specify a destination file to write." << sio.nl;
230 } 230 }
231 else 231 else
232 { 232 {
233 File fIn( opts.sFile, File::Write|File::Read ); 233 File fIn( opts.sFile, File::Write|File::Read );
234 Myriad m( fIn ); 234 Myriad m( fIn );
235 MyriadStream sIn = m.openStream( opts.iStream ); 235 MyriadStream sIn = m.openStream( opts.iStream );
236 File fOut( opts.sDst, File::Write|File::Create|File::Truncate ); 236 File fOut( opts.sDst, File::Write|File::Create|File::Truncate );
237 char buf[1024]; 237 char buf[1024];
238 while( !sIn.isEos() ) 238 while( !sIn.isEos() )
239 { 239 {
240 fOut.write( buf, sIn.read( buf, 1024 ) ); 240 fOut.write( buf, sIn.read( buf, 1024 ) );
241 } 241 }
242 } 242 }
243 break; 243 break;
244 244
245 case modeNone: 245 case modeNone:
246 sio << "Please select a mode, for more info, try --help." 246 sio << "Please select a mode, for more info, try --help."
247 << sio.nl << sio.nl; 247 << sio.nl << sio.nl;
248 break; 248 break;
249 } 249 }
250 250
251 return 0; 251 return 0;
252} 252}
253 253
diff --git a/src/tools/viewcsv.cpp b/src/tools/viewcsv.cpp
index 5009ea8..328cafc 100644
--- a/src/tools/viewcsv.cpp
+++ b/src/tools/viewcsv.cpp
@@ -20,33 +20,33 @@ using namespace Bu;
20class Options : public Bu::OptParser 20class Options : public Bu::OptParser
21{ 21{
22public: 22public:
23 Options( int argc, char *argv[] ) : 23 Options( int argc, char *argv[] ) :
24 bHeader( true ) 24 bHeader( true )
25 { 25 {
26 addOption( bHeader, "no-header", 26 addOption( bHeader, "no-header",
27 "Don't use the first line as a header row. This behaviour can " 27 "Don't use the first line as a header row. This behaviour can "
28 "also be toggled while running with 'h'." ); 28 "also be toggled while running with 'h'." );
29 setNonOption( slot( this, &Options::onNonOption ) ); 29 setNonOption( slot( this, &Options::onNonOption ) );
30 addHelpOption(); 30 addHelpOption();
31 31
32 setOverride( "no-header", "true" ); 32 setOverride( "no-header", "true" );
33 parse( argc, argv ); 33 parse( argc, argv );
34 } 34 }
35 35
36 virtual ~Options() 36 virtual ~Options()
37 { 37 {
38 } 38 }
39 39
40 int onNonOption( StrArray aParams ) 40 int onNonOption( StrArray aParams )
41 { 41 {
42 //sio << aParams << sio.nl; 42 //sio << aParams << sio.nl;
43 sFileIn = aParams[0]; 43 sFileIn = aParams[0];
44 44
45 return 0; 45 return 0;
46 } 46 }
47 47
48 Bu::String sFileIn; 48 Bu::String sFileIn;
49 bool bHeader; 49 bool bHeader;
50}; 50};
51 51
52typedef Bu::Array<StrArray> StrGrid; 52typedef Bu::Array<StrArray> StrGrid;
@@ -54,421 +54,421 @@ typedef Bu::Array<int> IntArray;
54class CsvDoc 54class CsvDoc
55{ 55{
56public: 56public:
57 CsvDoc() : 57 CsvDoc() :
58 iMaxCols( 0 ) 58 iMaxCols( 0 )
59 { 59 {
60 } 60 }
61 61
62 virtual ~CsvDoc() 62 virtual ~CsvDoc()
63 { 63 {
64 } 64 }
65 65
66 void addRow( StrArray aStr ) 66 void addRow( StrArray aStr )
67 { 67 {
68 sgData.append( aStr ); 68 sgData.append( aStr );
69 if( iMaxCols < aStr.getSize() ) 69 if( iMaxCols < aStr.getSize() )
70 iMaxCols = aStr.getSize(); 70 iMaxCols = aStr.getSize();
71 while( aWidths.getSize() < iMaxCols ) 71 while( aWidths.getSize() < iMaxCols )
72 { 72 {
73 aWidths.append( 0 ); 73 aWidths.append( 0 );
74 } 74 }
75 for( int j = 0; j < aStr.getSize(); j++ ) 75 for( int j = 0; j < aStr.getSize(); j++ )
76 { 76 {
77 if( aWidths[j] < aStr[j].getSize() ) 77 if( aWidths[j] < aStr[j].getSize() )
78 aWidths[j] = aStr[j].getSize(); 78 aWidths[j] = aStr[j].getSize();
79 } 79 }
80 } 80 }
81 81
82 int iMaxCols; 82 int iMaxCols;
83 StrGrid sgData; 83 StrGrid sgData;
84 IntArray aWidths; 84 IntArray aWidths;
85}; 85};
86 86
87class CsvView 87class CsvView
88{ 88{
89public: 89public:
90 CsvView( CsvDoc &doc ) : 90 CsvView( CsvDoc &doc ) :
91 doc( doc ), 91 doc( doc ),
92 iXOff( 0 ), 92 iXOff( 0 ),
93 iYOff( 0 ), 93 iYOff( 0 ),
94 bHeaderRow( false ) 94 bHeaderRow( false )
95 { 95 {
96 } 96 }
97 97
98 virtual ~CsvView() 98 virtual ~CsvView()
99 { 99 {
100 } 100 }
101 101
102 void render() 102 void render()
103 { 103 {
104 erase(); 104 erase();
105 int maxx, maxy; 105 int maxx, maxy;
106 getmaxyx( stdscr, maxy, maxx ); 106 getmaxyx( stdscr, maxy, maxx );
107 107
108 int iRows = buMin( (int)doc.sgData.getSize(), maxy-((bHeaderRow)?(4):(3)) ); 108 int iRows = buMin( (int)doc.sgData.getSize(), maxy-((bHeaderRow)?(4):(3)) );
109 int iCols = buMin( doc.iMaxCols, (int)maxx-1 ); 109 int iCols = buMin( doc.iMaxCols, (int)maxx-1 );
110 110
111 int iHdrHeight = 1; 111 int iHdrHeight = 1;
112 if( bHeaderRow ) 112 if( bHeaderRow )
113 iHdrHeight++; 113 iHdrHeight++;
114 114
115 // Draw the headers 115 // Draw the headers
116 for( int iRow = 0; iRow < iRows; iRow++ ) 116 for( int iRow = 0; iRow < iRows; iRow++ )
117 { 117 {
118 if( iRow+iYOff >= doc.sgData.getSize() ) 118 if( iRow+iYOff >= doc.sgData.getSize() )
119 break; 119 break;
120 char buf[6]; 120 char buf[6];
121 snprintf( buf, 6, "%5d", iRow+iYOff ); 121 snprintf( buf, 6, "%5d", iRow+iYOff );
122 mvaddnstr( iRow+iHdrHeight+1, 0, buf, 5 ); 122 mvaddnstr( iRow+iHdrHeight+1, 0, buf, 5 );
123 mvaddch( iRow+iHdrHeight+1, 6, ACS_VLINE ); 123 mvaddch( iRow+iHdrHeight+1, 6, ACS_VLINE );
124 } 124 }
125 int iXPos = 6; 125 int iXPos = 6;
126 try 126 try
127 { 127 {
128 for( int iCol = 0; iCol < iCols; iCol++ ) 128 for( int iCol = 0; iCol < iCols; iCol++ )
129 { 129 {
130 if( iXPos >= maxx ) 130 if( iXPos >= maxx )
131 break; 131 break;
132 int iWidth = buMin( doc.aWidths[iCol+iXOff], maxx-iXPos-1 ); 132 int iWidth = buMin( doc.aWidths[iCol+iXOff], maxx-iXPos-1 );
133 char buf[6]; 133 char buf[6];
134 snprintf( buf, 6, "%d", iCol+iXOff ); 134 snprintf( buf, 6, "%d", iCol+iXOff );
135 mvaddch( 0, iXPos, ACS_VLINE ); 135 mvaddch( 0, iXPos, ACS_VLINE );
136 mvaddch( iHdrHeight, iXPos, ACS_PLUS ); 136 mvaddch( iHdrHeight, iXPos, ACS_PLUS );
137 mvaddnstr( 0, iXPos+1, buf, 5 ); 137 mvaddnstr( 0, iXPos+1, buf, 5 );
138 if( bHeaderRow ) 138 if( bHeaderRow )
139 { 139 {
140 mvaddnstr( 140 mvaddnstr(
141 1, iXPos+1, doc.sgData[0][iCol+iXOff].getStr(), iWidth 141 1, iXPos+1, doc.sgData[0][iCol+iXOff].getStr(), iWidth
142 ); 142 );
143 mvaddch( 1, iXPos, ACS_VLINE ); 143 mvaddch( 1, iXPos, ACS_VLINE );
144 } 144 }
145 for( int j = 0; j < iWidth; j++ ) 145 for( int j = 0; j < iWidth; j++ )
146 { 146 {
147 mvaddch( iHdrHeight, iXPos+j+1, ACS_HLINE ); 147 mvaddch( iHdrHeight, iXPos+j+1, ACS_HLINE );
148 } 148 }
149 iXPos += iWidth+1; 149 iXPos += iWidth+1;
150 } 150 }
151 } 151 }
152 catch(...) { } 152 catch(...) { }
153 for( int j = 0; j < 6; j++ ) 153 for( int j = 0; j < 6; j++ )
154 { 154 {
155 mvaddch( iHdrHeight, j, ACS_HLINE ); 155 mvaddch( iHdrHeight, j, ACS_HLINE );
156 } 156 }
157 157
158 // Draw some data 158 // Draw some data
159 for( int iRow = 0; iRow < iRows; iRow++ ) 159 for( int iRow = 0; iRow < iRows; iRow++ )
160 { 160 {
161 try 161 try
162 { 162 {
163 int iXPos = 6; 163 int iXPos = 6;
164 for( int iCol = 0; iCol < iCols; iCol++ ) 164 for( int iCol = 0; iCol < iCols; iCol++ )
165 { 165 {
166 if( iXPos >= maxx ) 166 if( iXPos >= maxx )
167 break; 167 break;
168 int iWidth = buMin( doc.aWidths[iCol+iXOff], maxx-iXPos-1 ); 168 int iWidth = buMin( doc.aWidths[iCol+iXOff], maxx-iXPos-1 );
169 mvaddch( iRow+iHdrHeight+1, iXPos, ACS_VLINE ); 169 mvaddch( iRow+iHdrHeight+1, iXPos, ACS_VLINE );
170 mvaddnstr( iRow+iHdrHeight+1, iXPos+1, 170 mvaddnstr( iRow+iHdrHeight+1, iXPos+1,
171 doc.sgData[iRow+iYOff][iCol+iXOff].getStr(), iWidth ); 171 doc.sgData[iRow+iYOff][iCol+iXOff].getStr(), iWidth );
172 iXPos += iWidth+1; 172 iXPos += iWidth+1;
173 } 173 }
174 } catch(...) { } 174 } catch(...) { }
175 } 175 }
176 176
177 attron( A_REVERSE ); 177 attron( A_REVERSE );
178 for( int j = 0; j < maxx; j++ ) 178 for( int j = 0; j < maxx; j++ )
179 { 179 {
180 mvaddch( maxy-1, j, ' ' ); 180 mvaddch( maxy-1, j, ' ' );
181 } 181 }
182 mvaddstr( maxy-1, 1, "q) quit h) toggle header row" ); 182 mvaddstr( maxy-1, 1, "q) quit h) toggle header row" );
183 char buf[30]; 183 char buf[30];
184 int iWidth = sprintf( buf, "[%dx%ld]", 184 int iWidth = sprintf( buf, "[%dx%ld]",
185 doc.iMaxCols, doc.sgData.getSize() 185 doc.iMaxCols, doc.sgData.getSize()
186 ); 186 );
187 mvaddstr( maxy-1, maxx-iWidth-1, buf ); 187 mvaddstr( maxy-1, maxx-iWidth-1, buf );
188 attroff( A_REVERSE ); 188 attroff( A_REVERSE );
189 } 189 }
190 190
191 void move( int iX, int iY ) 191 void move( int iX, int iY )
192 { 192 {
193 iXOff += iX; 193 iXOff += iX;
194 iYOff += iY; 194 iYOff += iY;
195 if( iXOff < 0 ) 195 if( iXOff < 0 )
196 iXOff = 0; 196 iXOff = 0;
197 197
198 if( bHeaderRow ) 198 if( bHeaderRow )
199 { 199 {
200 if( iYOff < 1 ) 200 if( iYOff < 1 )
201 iYOff = 1; 201 iYOff = 1;
202 } 202 }
203 else 203 else
204 { 204 {
205 if( iYOff < 0 ) 205 if( iYOff < 0 )
206 iYOff = 0; 206 iYOff = 0;
207 } 207 }
208 208
209 if( iYOff >= doc.sgData.getSize() ) 209 if( iYOff >= doc.sgData.getSize() )
210 iYOff = doc.sgData.getSize()-1; 210 iYOff = doc.sgData.getSize()-1;
211 211
212 if( iXOff >= doc.iMaxCols ) 212 if( iXOff >= doc.iMaxCols )
213 iXOff = doc.iMaxCols-1; 213 iXOff = doc.iMaxCols-1;
214 } 214 }
215 215
216 void pageDown() 216 void pageDown()
217 { 217 {
218 int maxx, maxy; 218 int maxx, maxy;
219 getmaxyx( stdscr, maxy, maxx ); 219 getmaxyx( stdscr, maxy, maxx );
220 move( 0, maxy-((bHeaderRow)?(4):(3)) ); 220 move( 0, maxy-((bHeaderRow)?(4):(3)) );
221 } 221 }
222 222
223 void pageUp() 223 void pageUp()
224 { 224 {
225 int maxx, maxy; 225 int maxx, maxy;
226 getmaxyx( stdscr, maxy, maxx ); 226 getmaxyx( stdscr, maxy, maxx );
227 move( 0, -(maxy-((bHeaderRow)?(4):(3))) ); 227 move( 0, -(maxy-((bHeaderRow)?(4):(3))) );
228 } 228 }
229 229
230 void home() 230 void home()
231 { 231 {
232 iYOff = 0; 232 iYOff = 0;
233 if( bHeaderRow ) iYOff++; 233 if( bHeaderRow ) iYOff++;
234 } 234 }
235 235
236 void end() 236 void end()
237 { 237 {
238 iYOff = doc.sgData.getSize()-1; 238 iYOff = doc.sgData.getSize()-1;
239 } 239 }
240 240
241 void setHeaderRow( bool bOn ) 241 void setHeaderRow( bool bOn )
242 { 242 {
243 if( bHeaderRow == bOn ) 243 if( bHeaderRow == bOn )
244 return; 244 return;
245 245
246 bHeaderRow = bOn; 246 bHeaderRow = bOn;
247 move( 0, ((bOn)?(1):(-1)) ); 247 move( 0, ((bOn)?(1):(-1)) );
248 } 248 }
249 249
250 void toggleHeaderRow() 250 void toggleHeaderRow()
251 { 251 {
252 setHeaderRow( !bHeaderRow ); 252 setHeaderRow( !bHeaderRow );
253 } 253 }
254 254
255 Bu::String prompt( const Bu::String &sPrompt ) 255 Bu::String prompt( const Bu::String &sPrompt )
256 { 256 {
257 int maxx, maxy; 257 int maxx, maxy;
258 Bu::String sStr; 258 Bu::String sStr;
259 259
260 RegEx re( sPrompt ); 260 RegEx re( sPrompt );
261 261
262 curs_set( 1 ); 262 curs_set( 1 );
263 for(;;) 263 for(;;)
264 { 264 {
265 getmaxyx( stdscr, maxy, maxx ); 265 getmaxyx( stdscr, maxy, maxx );
266 for( int j = 0; j < maxx; j++ ) 266 for( int j = 0; j < maxx; j++ )
267 { 267 {
268 mvaddch( maxy-1, j, ' ' ); 268 mvaddch( maxy-1, j, ' ' );
269 } 269 }
270 mvaddstr( maxy-1, 0, sPrompt.getStr() ); 270 mvaddstr( maxy-1, 0, sPrompt.getStr() );
271 271
272 mvaddstr( maxy-1, sPrompt.getSize(), sStr.getStr() ); 272 mvaddstr( maxy-1, sPrompt.getSize(), sStr.getStr() );
273 273
274 int iCh = getch(); 274 int iCh = getch();
275 switch( iCh ) 275 switch( iCh )
276 { 276 {
277 case '\n': 277 case '\n':
278 case '\r': 278 case '\r':
279 case KEY_ENTER: 279 case KEY_ENTER:
280 curs_set( 0 ); 280 curs_set( 0 );
281 return sStr; 281 return sStr;
282 break; 282 break;
283 283
284 case KEY_BACKSPACE: 284 case KEY_BACKSPACE:
285 if( sStr.getSize() > 0 ) 285 if( sStr.getSize() > 0 )
286 sStr.resize( sStr.getSize()-1 ); 286 sStr.resize( sStr.getSize()-1 );
287 break; 287 break;
288 288
289 default: 289 default:
290 if( iCh < 127 ) 290 if( iCh < 127 )
291 sStr += (char)iCh; 291 sStr += (char)iCh;
292 break; 292 break;
293 } 293 }
294 } 294 }
295 } 295 }
296 296
297 void resetCaret() 297 void resetCaret()
298 { 298 {
299 sysCaret.reset(); 299 sysCaret.reset();
300 } 300 }
301 301
302 void findNext( const Bu::String &sTerm ) 302 void findNext( const Bu::String &sTerm )
303 { 303 {
304 RegEx re( sTerm ); 304 RegEx re( sTerm );
305 305
306 int y = sysCaret.iRow; 306 int y = sysCaret.iRow;
307 if( y < 0 ) 307 if( y < 0 )
308 y = 0; 308 y = 0;
309 int x = sysCaret.iCol+1; 309 int x = sysCaret.iCol+1;
310 for( ; y < doc.sgData.getSize(); y++ ) 310 for( ; y < doc.sgData.getSize(); y++ )
311 { 311 {
312 StrArray &aRow = doc.sgData[y]; 312 StrArray &aRow = doc.sgData[y];
313 for( ; x < aRow.getSize(); x++ ) 313 for( ; x < aRow.getSize(); x++ )
314 { 314 {
315 if( re.execute( aRow[x] ) ) //aRow[x].find( sTerm ) ) 315 if( re.execute( aRow[x] ) ) //aRow[x].find( sTerm ) )
316 { 316 {
317 sysCaret.iRow = y; 317 sysCaret.iRow = y;
318 sysCaret.iCol = x; 318 sysCaret.iCol = x;
319 scrollToCaret(); 319 scrollToCaret();
320 return; 320 return;
321 } 321 }
322 } 322 }
323 x = 0; 323 x = 0;
324 } 324 }
325 } 325 }
326 326
327 void scrollToCaret() 327 void scrollToCaret()
328 { 328 {
329 iXOff = sysCaret.iCol; 329 iXOff = sysCaret.iCol;
330 iYOff = sysCaret.iRow; 330 iYOff = sysCaret.iRow;
331 } 331 }
332 332
333 CsvDoc &doc; 333 CsvDoc &doc;
334 int iXOff; 334 int iXOff;
335 int iYOff; 335 int iYOff;
336 bool bHeaderRow; 336 bool bHeaderRow;
337 337
338 class Caret 338 class Caret
339 { 339 {
340 public: 340 public:
341 Caret() : 341 Caret() :
342 iRow( -1 ), 342 iRow( -1 ),
343 iCol( -1 ) 343 iCol( -1 )
344 { 344 {
345 } 345 }
346 346
347 virtual ~Caret() 347 virtual ~Caret()
348 { 348 {
349 } 349 }
350 350
351 351
352 void reset() 352 void reset()
353 { 353 {
354 iRow = iCol = -1; 354 iRow = iCol = -1;
355 } 355 }
356 356
357 bool isSet() 357 bool isSet()
358 { 358 {
359 if( iRow < 0 || iCol < 0 ) 359 if( iRow < 0 || iCol < 0 )
360 return false; 360 return false;
361 return true; 361 return true;
362 } 362 }
363 363
364 int iRow; 364 int iRow;
365 int iCol; 365 int iCol;
366 }; 366 };
367 367
368 Caret sysCaret; 368 Caret sysCaret;
369}; 369};
370 370
371int main( int argc, char *argv[] ) 371int main( int argc, char *argv[] )
372{ 372{
373 Options opt( argc, argv ); 373 Options opt( argc, argv );
374 374
375 if( !opt.sFileIn.isSet() ) 375 if( !opt.sFileIn.isSet() )
376 { 376 {
377 sio << "No file specified." << sio.nl; 377 sio << "No file specified." << sio.nl;
378 return 1; 378 return 1;
379 } 379 }
380 380
381 CsvDoc doc; 381 CsvDoc doc;
382 { 382 {
383 File fIn( opt.sFileIn, File::Read ); 383 File fIn( opt.sFileIn, File::Read );
384 NewLine nlIn( fIn ); 384 NewLine nlIn( fIn );
385 Buffer bIn( nlIn ); 385 Buffer bIn( nlIn );
386 CsvReader cr( bIn ); 386 CsvReader cr( bIn );
387 387
388 while( !fIn.isEos() ) 388 while( !fIn.isEos() )
389 { 389 {
390 StrArray sa = cr.readLine(); 390 StrArray sa = cr.readLine();
391 if( fIn.isEos() ) 391 if( fIn.isEos() )
392 break; 392 break;
393 doc.addRow( sa ); 393 doc.addRow( sa );
394 } 394 }
395 } 395 }
396 396
397 initscr(); 397 initscr();
398 cbreak(); 398 cbreak();
399 noecho(); 399 noecho();
400 nonl(); 400 nonl();
401 intrflush( stdscr, FALSE ); 401 intrflush( stdscr, FALSE );
402 keypad( stdscr, TRUE ); 402 keypad( stdscr, TRUE );
403 curs_set( 0 ); 403 curs_set( 0 );
404 404
405 CsvView view( doc ); 405 CsvView view( doc );
406 view.setHeaderRow( opt.bHeader ); 406 view.setHeaderRow( opt.bHeader );
407 407
408 Bu::String sSearchTerm; 408 Bu::String sSearchTerm;
409 409
410 bool bRun = true; 410 bool bRun = true;
411 do 411 do
412 { 412 {
413 view.render(); 413 view.render();
414 414
415 int ch = getch(); 415 int ch = getch();
416 switch( ch ) 416 switch( ch )
417 { 417 {
418 case 'q': 418 case 'q':
419 bRun = false; 419 bRun = false;
420 break; 420 break;
421 421
422 case KEY_DOWN: 422 case KEY_DOWN:
423 view.move( 0, 1 ); 423 view.move( 0, 1 );
424 break; 424 break;
425 425
426 case KEY_UP: 426 case KEY_UP:
427 view.move( 0, -1 ); 427 view.move( 0, -1 );
428 break; 428 break;
429 429
430 case KEY_LEFT: 430 case KEY_LEFT:
431 view.move( -1, 0 ); 431 view.move( -1, 0 );
432 break; 432 break;
433 433
434 case KEY_RIGHT: 434 case KEY_RIGHT:
435 view.move( 1, 0 ); 435 view.move( 1, 0 );
436 break; 436 break;
437 437
438 case KEY_NPAGE: 438 case KEY_NPAGE:
439 view.pageDown(); 439 view.pageDown();
440 break; 440 break;
441 441
442 case KEY_PPAGE: 442 case KEY_PPAGE:
443 view.pageUp(); 443 view.pageUp();
444 break; 444 break;
445 445
446 case KEY_HOME: 446 case KEY_HOME:
447 view.home(); 447 view.home();
448 break; 448 break;
449 449
450 case KEY_END: 450 case KEY_END:
451 view.end(); 451 view.end();
452 break; 452 break;
453 453
454 case '/': 454 case '/':
455 sSearchTerm = view.prompt("find: "); 455 sSearchTerm = view.prompt("find: ");
456 view.resetCaret(); 456 view.resetCaret();
457 view.findNext( sSearchTerm ); 457 view.findNext( sSearchTerm );
458 break; 458 break;
459 459
460 case 'n': 460 case 'n':
461 view.findNext( sSearchTerm ); 461 view.findNext( sSearchTerm );
462 break; 462 break;
463 463
464 case 'h': 464 case 'h':
465 view.toggleHeaderRow(); 465 view.toggleHeaderRow();
466 break; 466 break;
467 } 467 }
468 } while( bRun ); 468 } while( bRun );
469 469
470 endwin(); 470 endwin();
471 471
472 return 0; 472 return 0;
473} 473}
474 474