Logo Search packages:      
Sourcecode: tagcoll version File versions  Download package

taggrep.cc

/*
 * tagged collection - Experimental programs to test and study tagged collections
 *
 * Copyright (C) 2003,2004,2005  Enrico Zini
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#define APPNAME PACKAGE
#else
#warning No config.h found: using fallback values
#define APPNAME __FILE__
#define VERSION "unknown"
#endif

#include "CommandlineParser.h"

#include <stdio.h>

#include <stdlib.h>     // getenv

#include <errno.h>

#include <tagcoll/stringf.h>
#include <tagcoll/Exception.h>
#include <tagcoll/Consumer.h>
#include <tagcoll/StdioParserInput.h>
#include <tagcoll/TextFormat.h>
#include <tagcoll/Expression.h>

#include <algorithm>

using namespace std;
using namespace Tagcoll;

void readCollection(const string& file, Consumer<string, string>& builder)
      throw (FileException, ParserException)
{
      Converter<string, string> conv;

      if (file == "-")
      {
            StdioParserInput input(stdin, "<stdin>");
            TextFormat<string, string>::parse(conv, conv, input, builder);
      }
      else
      {
            StdioParserInput input(file);
            TextFormat<string, string>::parse(conv, conv, input, builder);
      }
}

class CommandlineArgs
{
protected:
      int argc;
      const char** argv;
      int _next;

public:
      CommandlineArgs(int argc, const char* argv[]) throw () : argc(argc), argv(argv), _next(1) {}

      // Return true if there is another argument left in the list
      bool hasNext() const throw () { return argc >= _next + 1; }

      // Return the next argument in the list
      string next() throw ()
      {
            if (hasNext())
            {
                  return argv[_next++];
            } else {
                  return "-";
            }
      }
};

int main(int argc, const char* argv[])
{
      try {
            CommandlineParser opts(APPNAME, "[options] <tag-expression> [file1 [file2 [...]]]",
                        "Filter the contents of a tagged collection\n");
            opts.add("version", 0, "version", "print the program version, then exit");
            opts.add("invert-match", 'v', "invert-match", "invert the sense of matching, to select non-matching lines");
            opts.add("quiet", 'q', "quiet", "do not write anything to standard output, but exit with 0 if any match is found");

            // Process the commandline
            if (!opts.parse(argc, argv) || argc == 1)
            {
                  opts.printHelp();
                  return 1;
            }
            if (opts.get("help").defined())
            {
                  opts.printHelp();
                  return 0;
            }
            if (opts.get("version").defined())
            {
                  printf("%s ver." VERSION "\n", APPNAME);
                  return 0;
            }

            CommandlineArgs args(argc, argv);
            
            string expression = args.next();

            FilterChain<string, string> filters;

            FilterItemsByExpression<string, string> filter(expression);
            filters.appendFilter(filter);

            if (opts.get("invert-match").defined())
                  filter.setMatchType(FilterItemsByExpression<string, string>::INVERTED);

            Converter<string, string> conv;
            Sink<string, string> sink;
            TextFormat<string, string> output(conv, conv, stdout);
            if (opts.get("quiet").defined())
                  filters.setConsumer(sink);
            else
                  filters.setConsumer(output);

            do
            {
                  string file = args.next();
                  readCollection(file, filters);
            }
            while (args.hasNext());

            return filter.countMatched() > 0 ? 0 : 1;
      }
      catch (Exception& e)
      {
            fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
            return 1;
      }
}

// vim:set ts=4 sw=4:

Generated by  Doxygen 1.6.0   Back to index