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    // consume options
00107 
00108    FileName  me(*argv++);
00109 
00110    programName = me.basename();
00111 
00112    list<string> script;  // -e and -f options get accumulated into this 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    // when we get here, *argv will either be a null pointer or it will
00180    // point to the first input file.
00181 
00182    if(addPrint)
00183    {
00184        script.push_back("p");
00185    }
00186 
00187 
00189    // compile script
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    // execute the script on all incoming files
00214 
00215    if(*argv == 0)
00216    {
00217       // read from stdin and quit
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 }
Generated on Wed Feb 29 22:50:03 2012 for CXXUtilities by  doxygen 1.6.3