mus.cxx
Go to the documentation of this file.00001 #include <cxxtls/muSED.h>
00002 #include <cxxtls/file.h>
00003 #include <cxxtls/foreach.h>
00004
00005 #include <iostream>
00006 #include <fstream>
00007 #include <stdlib.h>
00008
00009 using namespace std;
00010 using namespace cxxtls;
00011
00014
00038
00039
00040 string programName;
00041
00042 static void printHelp();
00043
00044 static void bomb(string const &msg)
00045 {
00046 cerr << programName << " - fatal error: " << msg << endl;
00047 exit(1);
00048 }
00049
00050 static void apply(muSED::CompiledScript &script, list<string> const &container)
00051 {
00052 list<string> output;
00053
00054 muSED::apply(script, container, output);
00055
00056 CXXTLS_FOREACH(string const &cur, output)
00057 {
00058 cout << cur << endl;
00059 }
00060
00061 }
00062
00063 static void readFile(string const &name, list<string> &container)
00064 {
00065 if(name == "-")
00066 {
00067 string line;
00068
00069 while(getline(cin, line))
00070 {
00071 container.push_back(line);
00072 }
00073 }
00074 else
00075 {
00076 string line;
00077
00078 ifstream file(name.c_str());
00079
00080 if(!file.good())
00081 {
00082 bomb(string(" reading input file ") + name );
00083 }
00084
00085 while(getline(file, line))
00086 {
00087 container.push_back(line);
00088 }
00089
00090 }
00091 }
00092
00093
00094
00095 int main(int argc, char **argv)
00096 {
00097 if(argc == 1)
00098 {
00099 printHelp();
00100 exit(1);
00101 }
00102
00103
00105
00107
00108 FileName me(*argv++);
00109
00110 programName = me.basename();
00111
00112 list<string> script;
00113
00114 bool addPrint = true;
00115
00116 for(; *argv; ++argv)
00117 {
00118 char const *optionPtr = *argv;
00119
00120 if(optionPtr[0] != '-' || optionPtr[1] == 0 )
00121 {
00122 break;
00123 }
00124
00125 string option(optionPtr);
00126
00127 if(option == "-f")
00128 {
00129 ++argv;
00130
00131 if(*argv == 0)
00132 {
00133 bomb("expected script name after -f");
00134 }
00135
00136 ifstream scriptFragment(*argv);
00137
00138 if(!scriptFragment.good())
00139 {
00140 bomb(string("reading file ") + *argv);
00141 }
00142
00143 string line;
00144
00145 while(getline(scriptFragment, line))
00146 {
00147 script.push_back(line);
00148 }
00149
00150
00151 }
00152 else
00153 if(option == "-e")
00154 {
00155 ++argv;
00156
00157 if(*argv == 0)
00158 {
00159 bomb("expected script string after -e");
00160 }
00161
00162 script.push_back(*argv);
00163 }
00164 else
00165 if(option == "-n")
00166 {
00167 addPrint = false;
00168 }
00169 else if(option == "-h" || option == "--help")
00170 {
00171 printHelp();
00172 }
00173 else
00174 {
00175 bomb(string("unknown option: ") + *argv);
00176 }
00177 }
00178
00179
00180
00181
00182 if(addPrint)
00183 {
00184 script.push_back("p");
00185 }
00186
00187
00189
00191
00192 muSED::CompiledScript executor(script);
00193
00194 if(!executor.ok())
00195 {
00196 cerr << programName << " - fatal error in the following script" << endl;
00197
00198 int line=1;
00199
00200 CXXTLS_FOREACH(string const &cur, script)
00201 {
00202 cerr << "[" << line++ << "]=" << cur << endl;
00203 }
00204
00205 cerr << endl;
00206
00207 bomb(executor.error());
00208
00209 }
00210
00212
00214
00215 if(*argv == 0)
00216 {
00217
00218
00219 list<string> stdinContents;
00220
00221 readFile("-", stdinContents);
00222
00223 apply(executor, stdinContents);
00224
00225 }
00226 else
00227 {
00228 while(*argv != 0)
00229 {
00230 FileName name(*argv++);
00231
00232 list<string> fileContents;
00233
00234 readFile(name, fileContents);
00235
00236 apply(executor, fileContents);
00237
00238 }
00239 }
00240
00241
00242 exit(0);
00243 }
00244
00246 static void printHelp()
00247 {
00248 char const *lines[]=
00249 {
00250 "mus - MICRO-SED",
00251 "",
00252 "Usage:",
00253 " mus [options] [files]",
00254 "",
00255 "Description:",
00256 "",
00257 " mus is a micro-sed. It provides a proper subset of sed's capabilities",
00258 " but also provides additional commands and features that sed does not.",
00259 " mus is not preferred to sed, it exists to allow scripts consistent",
00260 " with the muSED implementation to be used to perform textual transformation.",
00261 "",
00262 "Options",
00263 "",
00264 " -f scriptName The name of file containing a mus script.",
00265 " -e scriptText A string defining a script.",
00266 " -n Suppresses automatic printing of every line.",
00267 " -h Print this help message",
00268 " --help Print this help message",
00269 "",
00270 "Online Documentation",
00271 " See http://www.bordoon.com/tools/index.html",
00272 " muSED",
00273 " muSED.h",
00274
00275 "",
00276 "",
00277 0
00278 };
00279
00280 char const **scan = lines;
00281
00282 while(*scan)
00283 {
00284 cout << *scan++ << endl;
00285 }
00286
00287 exit(1);
00288 }