You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2010/05/05 13:17:42 UTC

svn commit: r941250 - in /qpid/trunk/qpid: cpp/examples/messaging/ cpp/examples/messaging/extra_dist/ doc/book/src/

Author: gsim
Date: Wed May  5 11:17:41 2010
New Revision: 941250

URL: http://svn.apache.org/viewvc?rev=941250&view=rev
Log:
Some cleanup on examples:

* removed obsolete examples (queue-/topic-sender/receiver)
* removed the need to include headers with boost dependencies
* moved the argument handling in darin and spout closer to that of python (and update docs to reflect that)
* changed to ship a manually constructed makefile for messaging examples (generated one doesn't work and maintaining that seems like more work with little benefit)


Added:
    qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp
    qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h
    qpid/trunk/qpid/cpp/examples/messaging/extra_dist/
    qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile
Removed:
    qpid/trunk/qpid/cpp/examples/messaging/messaging_queue_receiver.vcproj
    qpid/trunk/qpid/cpp/examples/messaging/messaging_queue_sender.vcproj
    qpid/trunk/qpid/cpp/examples/messaging/messaging_topic_receiver.vcproj
    qpid/trunk/qpid/cpp/examples/messaging/messaging_topic_sender.vcproj
    qpid/trunk/qpid/cpp/examples/messaging/queue_receiver.cpp
    qpid/trunk/qpid/cpp/examples/messaging/queue_sender.cpp
    qpid/trunk/qpid/cpp/examples/messaging/topic_receiver.cpp
    qpid/trunk/qpid/cpp/examples/messaging/topic_sender.cpp
Modified:
    qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt
    qpid/trunk/qpid/cpp/examples/messaging/Makefile.am
    qpid/trunk/qpid/cpp/examples/messaging/drain.cpp
    qpid/trunk/qpid/cpp/examples/messaging/spout.cpp
    qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml

Modified: qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/CMakeLists.txt Wed May  5 11:17:41 2010
@@ -19,14 +19,26 @@
 
 # drain and spout have explicit Boost.program_options usage in them, so be
 # sure that lib is linked in.
-add_example(messaging drain ${Boost_PROGRAM_OPTIONS_LIBRARY})
-add_example(messaging spout ${Boost_PROGRAM_OPTIONS_LIBRARY})
 
-add_example(messaging queue_receiver)
-add_example(messaging queue_sender)
+macro(add_messaging_example example)
+  add_executable(${example} ${example}.cpp OptionParser.cpp)
+  set_target_properties(${example} PROPERTIES OUTPUT_NAME ${example})
+  target_link_libraries(${example} qpidclient ${_boost_libs_needed})
+  # For installs, don't install the built example; that would be pointless.
+  # Install the things a user needs to build the example on-site.
+  install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${example}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OptionParser.h ${CMAKE_CURRENT_SOURCE_DIR}/OptionParser.cpp
+           DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/messaging
+           COMPONENT ${QPID_COMPONENT_EXAMPLES})
+  if (MSVC)
+    install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/messaging_${example}.vcproj
+             DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/messaging
+             COMPONENT ${QPID_COMPONENT_EXAMPLES})
+  endif (MSVC)
 
-add_example(messaging topic_receiver)
-add_example(messaging topic_sender)
+endmacro(add_messaging_example)
+
+add_messaging_example(drain)
+add_messaging_example(spout)
 
 add_example(messaging map_receiver)
 add_example(messaging map_sender)

Modified: qpid/trunk/qpid/cpp/examples/messaging/Makefile.am
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/Makefile.am?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/Makefile.am (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/Makefile.am Wed May  5 11:17:41 2010
@@ -18,32 +18,23 @@
 #
 examplesdir=$(pkgdatadir)/examples/messaging
 
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
+# Settings to build the examples in automake
+AM_CXXFLAGS = $(WARNING_CFLAGS)
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include
+CLIENT_LIB=$(top_builddir)/src/libqpidclient.la
+CLIENTFLAGS=-lqpidclient
 
-noinst_PROGRAMS=drain spout queue_sender queue_receiver topic_sender topic_receiver client server map_sender map_receiver hello_world
+noinst_PROGRAMS=drain spout client server map_sender map_receiver hello_world
 
 hello_world_SOURCES=hello_world.cpp
 hello_world_LDADD=$(CLIENT_LIB)
 
-drain_SOURCES=drain.cpp
+drain_SOURCES=drain.cpp OptionParser.h OptionParser.cpp
 drain_LDADD=$(CLIENT_LIB)
 
-spout_SOURCES=spout.cpp
+spout_SOURCES=spout.cpp OptionParser.h OptionParser.cpp
 spout_LDADD=$(CLIENT_LIB)
 
-queue_sender_SOURCES=queue_sender.cpp
-queue_sender_LDADD=$(CLIENT_LIB)
-
-queue_receiver_SOURCES=queue_receiver.cpp
-queue_receiver_LDADD=$(CLIENT_LIB)
-
-topic_sender_SOURCES=topic_sender.cpp
-topic_sender_LDADD=$(CLIENT_LIB)
-
-topic_receiver_SOURCES=topic_receiver.cpp
-topic_receiver_LDADD=$(CLIENT_LIB)
-
 client_SOURCES=client.cpp
 client_LDADD=$(CLIENT_LIB)
 
@@ -56,15 +47,24 @@ map_sender_LDADD=$(CLIENT_LIB)
 map_receiver_SOURCES=map_receiver.cpp
 map_receiver_LDADD=$(CLIENT_LIB)
 
+examples_DATA=                 \
+	hello_world.cpp	       \
+	drain.cpp              \
+	spout.cpp              \
+	OptionParser.cpp       \
+	OptionParser.h         \
+	client.cpp             \
+	server.cpp             \
+	map_sender.cpp         \
+	map_receiver.cpp       \
+        extra_dist/Makefile
+
 EXTRA_DIST=                  \
+	$(examples_DATA)     \
 	CMakeLists.txt \
 	messaging_client.vcproj \
 	messaging_drain.vcproj \
 	messaging_map_receiver.vcproj \
 	messaging_map_sender.vcproj \
-	messaging_queue_receiver.vcproj \
-	messaging_queue_sender.vcproj \
 	messaging_server.vcproj \
-	messaging_spout.vcproj \
-	messaging_topic_receiver.vcproj \
-	messaging_topic_sender.vcproj
+	messaging_spout.vcproj

Added: qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/OptionParser.cpp Wed May  5 11:17:41 2010
@@ -0,0 +1,257 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "OptionParser.h"
+#include <qpid/types/Exception.h>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+
+class Option
+{
+  public:
+    Option(const std::string& name, const std::string& description);
+    virtual ~Option() {}
+    virtual void setValue(const std::string&) = 0;
+    virtual bool isValueExpected() = 0;
+    bool match(const std::string&);
+    std::ostream& print(std::ostream& out);
+  private:
+    std::string longName;
+    std::string shortName;
+    std::string description;
+    std::ostream& printNames(std::ostream& out);
+  friend class OptionParser;
+};
+
+class StringOption : public Option
+{
+  public:
+    StringOption(const std::string& name, const std::string& description, std::string& v) : Option(name, description), value(v) {}
+    void setValue(const std::string& v) { value = v; }
+    bool isValueExpected() { return true; }
+  private:
+    std::string& value;
+};
+
+class IntegerOption : public Option
+{
+  public:
+    IntegerOption(const std::string& name, const std::string& description, int& v) : Option(name, description), value(v) {}
+    void setValue(const std::string& v) { value = atoi(v.c_str()); }
+    bool isValueExpected() { return true; }
+  private:
+    int& value;
+};
+
+class BooleanOption : public Option
+{
+  public:
+    BooleanOption(const std::string& name, const std::string& description, bool& v) : Option(name, description), value(v) {}
+    void setValue(const std::string&) { value = true; }
+    bool isValueExpected() { return false; }
+  private:
+    bool& value;
+};
+
+class MultiStringOption : public Option
+{
+  public:
+    MultiStringOption(const std::string& name, const std::string& description, std::vector<std::string>& v) : Option(name, description), value(v) {}
+    void setValue(const std::string& v) { value.push_back(v); }
+    bool isValueExpected() { return true; }
+  private:
+    std::vector<std::string>& value;
+};
+
+class OptionMatch
+{
+  public:
+    OptionMatch(const std::string& argument);
+    bool operator()(Option* option);
+    bool isOption();
+  private:
+    std::string name;
+};
+
+class OptionsError : public qpid::types::Exception
+{
+  public:
+    OptionsError(const std::string& message) : qpid::types::Exception(message) {}
+};
+
+Option::Option(const std::string& name, const std::string& desc) : description(desc)
+{
+    std::string::size_type i = name.find(",");
+    if (i != std::string::npos) {
+        longName = name.substr(0, i);
+        if (i + 1 < name.size())
+            shortName = name.substr(i+1);
+    } else {
+        longName = name;
+    }
+}
+
+bool Option::match(const std::string& name)
+{
+    return name == longName || name == shortName;
+}
+
+std::ostream& Option::printNames(std::ostream& out)
+{
+    if (shortName.size()) {
+        out << "-" << shortName;
+        if (isValueExpected()) out << " VALUE";
+        out << ", --" << longName;
+        if (isValueExpected()) out << " VALUE";
+    } else {
+        out << "--" << longName;
+        if (isValueExpected()) out << " VALUE";
+    }
+    return out;
+}
+
+std::ostream& Option::print(std::ostream& out)
+{
+    std::stringstream names;
+    printNames(names);
+    out << std::setw(30) << std::left << names.str() << description << std::endl;
+    return out;
+}
+
+std::vector<std::string>& OptionParser::getArguments() { return arguments; }
+
+void OptionParser::add(Option* option)
+{
+    options.push_back(option);
+}
+
+void OptionParser::add(const std::string& name, std::string& value, const std::string& description)
+{
+    add(new StringOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, int& value, const std::string& description)
+{
+    add(new IntegerOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, bool& value, const std::string& description)
+{
+    add(new BooleanOption(name, description, value));
+}
+void OptionParser::add(const std::string& name, std::vector<std::string>& value, const std::string& description)
+{
+    add(new MultiStringOption(name, description, value));
+}
+
+OptionMatch::OptionMatch(const std::string& argument)
+{
+    if (argument.find("--") == 0) {
+        name = argument.substr(2);
+    } else if (argument.find("-") == 0) {
+        name = argument.substr(1);
+    }
+}
+
+bool OptionMatch::operator()(Option* option)
+{
+    return option->match(name);
+}
+
+bool OptionMatch::isOption()
+{
+    return name.size();
+}
+
+OptionParser::OptionParser(const std::string& s, const std::string& d) : summary(s), description(d), help(false)
+{
+    add("help,h", help, "show this message");
+}
+
+Option* OptionParser::getOption(const std::string& argument)
+{
+    OptionMatch match(argument);
+    if (match.isOption()) {
+        Options::iterator i = std::find_if(options.begin(), options.end(), match);
+        if (i == options.end()) {
+            std::stringstream error;
+            error << "Unrecognised option: " << argument;
+            throw OptionsError(error.str());
+        } else {
+            return *i;
+        }        
+    } else {
+        return 0;
+    }
+}
+
+void OptionParser::error(const std::string& message)
+{
+    std::cout << summary << std::endl << std::endl;
+    std::cerr << "Error: " << message << "; try --help for more information" << std::endl;
+}
+
+bool OptionParser::parse(int argc, char** argv)
+{
+    try {
+        for (int i = 1; i < argc; ++i) {
+            std::string argument = argv[i];
+            Option* o = getOption(argument);
+            if (o) {
+                if (o->isValueExpected()) {
+                    if (i + 1 < argc) {
+                        o->setValue(argv[++i]);
+                    } else {
+                        std::stringstream error;
+                        error << "Value expected for option " << o->longName;
+                        throw OptionsError(error.str());
+                    }
+                } else {
+                    o->setValue("");
+                }
+            } else {
+                arguments.push_back(argument);
+            }
+        }
+        if (help) {
+            std::cout << summary << std::endl << std::endl;
+            std::cout << description << std::endl << std::endl;
+            std::cout << "Options: " << std::endl;
+            for (Options::iterator i = options.begin(); i != options.end(); ++i) {
+                (*i)->print(std::cout);
+            }
+            return false;
+        } else {
+            return true;
+        }
+    } catch (const std::exception& e) {
+        error(e.what());
+        return false;
+    }
+}
+
+
+OptionParser::~OptionParser()
+{
+    for (Options::iterator i = options.begin(); i != options.end(); ++i) {        
+        delete *i;
+    }
+}

Added: qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/OptionParser.h Wed May  5 11:17:41 2010
@@ -0,0 +1,56 @@
+#ifndef OPTIONPARSER_H
+#define OPTIONPARSER_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Option;
+
+class OptionParser
+{
+  public:
+    OptionParser(const std::string& usage, const std::string& description);
+    ~OptionParser();
+    void add(const std::string& name, std::string& value, const std::string& description = std::string());
+    void add(const std::string& name, int& value, const std::string& description = std::string());
+    void add(const std::string& name, bool& value, const std::string& description = std::string());
+    void add(const std::string& name, std::vector<std::string>& value, const std::string& description = std::string());
+    bool parse(int argc, char** argv);
+    void error(const std::string& message);
+    std::vector<std::string>& getArguments();
+  private:
+    typedef std::vector<Option*> Options;
+
+    const std::string summary;
+    const std::string description;
+    bool help;
+    Options options;
+    std::vector<std::string> arguments;
+
+    void add(Option*);
+    Option* getOption(const std::string& argument);
+};
+
+#endif  /*!OPTIONPARSER_H*/

Modified: qpid/trunk/qpid/cpp/examples/messaging/drain.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/drain.cpp?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/drain.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/drain.cpp Wed May  5 11:17:41 2010
@@ -23,76 +23,56 @@
 #include <qpid/messaging/Message.h>
 #include <qpid/messaging/Receiver.h>
 #include <qpid/messaging/Session.h>
-#include <qpid/Exception.h>
-#include <qpid/Options.h>
-#include <qpid/log/Logger.h>
-#include <qpid/log/Options.h>
 
 #include <iostream>
 
+#include "OptionParser.h"
+
 using namespace qpid::messaging;
 using namespace qpid::types;
 
-struct Options : public qpid::Options
+struct Options : OptionParser
 {
-    bool help;
     std::string url;
     std::string address;
     std::string connectionOptions;
-    int64_t timeout;
+    int timeout;
     bool forever;
-    qpid::log::Options log;
 
-    Options(const std::string& argv0=std::string())
-        : qpid::Options("Options"),
-          help(false),
-          url("amqp:tcp:127.0.0.1"),
+    Options()
+        : OptionParser("Usage: drain [OPTIONS] ADDRESS", "Drains messages from the specified address"),
+          url("127.0.0.1"),
           timeout(0),
-          forever(false),
-          log(argv0)
+          forever(false)
     {
-        addOptions()
-            ("broker,b", qpid::optValue(url, "URL"), "url of broker to connect to")
-            ("address,a", qpid::optValue(address, "ADDRESS"), "address to drain from")
-            ("timeout,t", qpid::optValue(timeout, "TIMEOUT"), "timeout in seconds to wait before exiting")
-            ("forever,f", qpid::optValue(forever), "ignore timeout and wait forever")
-            ("connection-options", qpid::optValue(connectionOptions,"OPTIONS"), "connection options string in the form {name1=value1, name2=value2}")
-            ("help", qpid::optValue(help), "print this usage statement");
-        add(log);
+        add("broker,b", url, "url of broker to connect to");
+        add("timeout,t", timeout, "timeout in seconds to wait before exiting");
+        add("forever,f", forever, "ignore timeout and wait forever");
+        add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
     }
 
     Duration getTimeout()
     {
         if (forever) return Duration::FOREVER;
         else return timeout*Duration::SECOND;
-
     }
-    bool parse(int argc, char** argv)
+    
+    bool checkAddress()
     {
-        try {
-            qpid::Options::parse(argc, argv);
-            if (address.empty()) throw qpid::Exception("Address must be specified!");
-            qpid::log::Logger::instance().configure(log);
-            if (help) {
-                std::ostringstream msg;
-                std::cout << msg << *this << std::endl << std::endl 
-                          << "Drains messages from the specified address" << std::endl;
-                return false;
-            } else {
-                return true;
-            }
-        } catch (const std::exception& e) {
-            std::cerr << *this << std::endl << std::endl << e.what() << std::endl;
+        if (getArguments().empty()) {
+            error("Address is required");
             return false;
+        } else {
+            address = getArguments()[0];
+            return true;
         }
     }
 };
 
-
 int main(int argc, char** argv)
 {
-    Options options(argv[0]);
-    if (options.parse(argc, argv)) {
+    Options options;
+    if (options.parse(argc, argv) && options.checkAddress()) {
         Connection connection(options.url, options.connectionOptions);
         try {
             connection.open();

Added: qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile?rev=941250&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile (added)
+++ qpid/trunk/qpid/cpp/examples/messaging/extra_dist/Makefile Wed May  5 11:17:41 2010
@@ -0,0 +1,12 @@
+CXX=g++
+CXXFLAGS=-g -O2
+LDFLAGS=-lqpidclient
+
+all: drain spout client server map_sender map_receiver hello_world
+
+drain: drain.o OptionParser.o
+
+spout: spout.o OptionParser.o
+
+clean:
+	rm -f drain spout client server map_sender map_receiver hello_world *.o

Modified: qpid/trunk/qpid/cpp/examples/messaging/spout.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/spout.cpp?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/spout.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/spout.cpp Wed May  5 11:17:41 2010
@@ -25,16 +25,13 @@
 #include <qpid/messaging/Sender.h>
 #include <qpid/messaging/Session.h>
 #include <qpid/types/Variant.h>
-#include <qpid/Exception.h>
-#include <qpid/Options.h>
-#include <qpid/log/Logger.h>
-#include <qpid/log/Options.h>
 #include <qpid/sys/Time.h>
 
 #include <iostream>
+#include <sstream>
 #include <vector>
 
-#include <boost/format.hpp>
+#include "OptionParser.h"
 
 using namespace qpid::messaging;
 using namespace qpid::types;
@@ -44,62 +41,34 @@ using qpid::sys::TIME_INFINITE;
 
 typedef std::vector<std::string> string_vector;
 
-struct Options : public qpid::Options
+struct Options : OptionParser
 {
-    bool help;
     std::string url;
     std::string address;
-    int64_t timeout;
-    uint count;
+    int timeout;
+    int count;
     std::string id;
     std::string replyto;
     string_vector properties;
     string_vector entries;
     std::string content;
     std::string connectionOptions;
-    qpid::log::Options log;
 
-    Options(const std::string& argv0=std::string())
-        : qpid::Options("Options"),
-          help(false),
-          url("amqp:tcp:127.0.0.1"),
-          timeout(TIME_INFINITE),
-          count(1),
-          log(argv0)
-    {
-        addOptions()
-            ("broker,b", qpid::optValue(url, "URL"), "url of broker to connect to")
-            ("address,a", qpid::optValue(address, "ADDRESS"), "address to drain from")
-            ("timeout,t", qpid::optValue(timeout, "TIMEOUT"), "exit after the specified time")
-            ("count,c", qpid::optValue(count, "COUNT"), "stop after count messages have been sent, zero disables")
-            ("id,i", qpid::optValue(id, "ID"), "use the supplied id instead of generating one")
-            ("reply-to", qpid::optValue(replyto, "REPLY-TO"), "specify reply-to address")
-            ("property,P", qpid::optValue(properties, "NAME=VALUE"), "specify message property")
-            ("map,M", qpid::optValue(entries, "NAME=VALUE"), "specify entry for map content")
-            ("content", qpid::optValue(content, "CONTENT"), "specify textual content")
-            ("connection-options", qpid::optValue(connectionOptions,"OPTIONS"), "connection options string in the form {name1=value1, name2=value2}")
-            ("help", qpid::optValue(help), "print this usage statement");
-        add(log);
-    }
-
-    bool parse(int argc, char** argv)
-    {
-        try {
-            qpid::Options::parse(argc, argv);
-            if (address.empty()) throw qpid::Exception("Address must be specified!");
-            qpid::log::Logger::instance().configure(log);
-            if (help) {
-                std::ostringstream msg;
-                std::cout << msg << *this << std::endl << std::endl 
-                          << "Drains messages from the specified address" << std::endl;
-                return false;
-            } else {
-                return true;
-            }
-        } catch (const std::exception& e) {
-            std::cerr << *this << std::endl << std::endl << e.what() << std::endl;
-            return false;
-        }
+    Options()
+        : OptionParser("Usage: spout [OPTIONS] ADDRESS", "Send messages to the specified address"),
+          url("127.0.0.1"),
+          timeout(0),
+          count(1)
+    {
+        add("broker,b", url, "url of broker to connect to");
+        add("timeout,t", timeout, "exit after the specified time");
+        add("count,c", count, "stop after count messages have been sent, zero disables");
+        add("id,i", id, "use the supplied id instead of generating one");
+        add("reply-to", replyto, "specify reply-to address");
+        add("property,P", properties, "specify message property");
+        add("map,M", entries, "specify entry for map content");
+        add("content", content, "specify textual content");
+        add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
     }
 
     static bool nameval(const std::string& in, std::string& name, std::string& value)
@@ -149,13 +118,24 @@ struct Options : public qpid::Options
             }
         }
     }
+
+    bool checkAddress()
+    {
+        if (getArguments().empty()) {
+            error("Address is required");
+            return false;
+        } else {
+            address = getArguments()[0];
+            return true;
+        }
+    }
 };
 
 
 int main(int argc, char** argv)
 {
-    Options options(argv[0]);
-    if (options.parse(argc, argv)) {        
+    Options options;
+    if (options.parse(argc, argv) && options.checkAddress()) {
         Connection connection(options.url, options.connectionOptions);
         try {
             connection.open();
@@ -172,12 +152,15 @@ int main(int argc, char** argv)
                 message.setContent(options.content);
                 message.setContentType("text/plain");
             }
-            AbsTime end(now(), options.timeout);
-            for (uint count = 0; (count < options.count || options.count == 0) && end > now(); count++) {
+            AbsTime end(now(), options.timeout * qpid::sys::TIME_SEC);
+            for (int count = 0; (count < options.count || options.count == 0) && (options.timeout == 0 || end > now()); count++) {
                 if (!options.replyto.empty()) message.setReplyTo(Address(options.replyto));
                 std::string id = options.id.empty() ? Uuid(true).str() : options.id;
-                message.getProperties()["spout-id"] = (boost::format("%1%:%2%") % id % count).str();
+                std::stringstream spoutid;
+                spoutid << id << ":" << count;
+                message.getProperties()["spout-id"] = spoutid.str();
                 sender.send(message);
+                std::cout << "Sent " << (count+1) << " of " << options.count << " messages" <<std::endl; 
             }
             connection.close();
             return 0;

Modified: qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml?rev=941250&r1=941249&r2=941250&view=diff
==============================================================================
--- qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml (original)
+++ qpid/trunk/qpid/doc/book/src/Programming-In-Apache-Qpid.xml Wed May  5 11:17:41 2010
@@ -305,8 +305,8 @@ finally:
 
         <screen>
 $ qpid-config add queue hello-world
-$ ./spout -a hello-world
-$ ./drain -a hello-world
+$ ./spout hello-world
+$ ./drain hello-world
 
 Message(properties={spout-id:c877e622-d57b-4df2-bf3e-6014c68da0ea:0}, content='')
         </screen>
@@ -319,7 +319,7 @@ Message(properties={spout-id:c877e622-d5
 	<command>drain</command> one more time, no messages will be retrieved.</para>
 
         <screen>
-$ ./drain -a hello-world
+$ ./drain hello-world
 $
 	</screen>
 
@@ -342,8 +342,8 @@ $ qpid-config add exchange topic hello-w
 	<para>Now run <command>drain</command> and <command>spout</command> the same way we did in the previous example:</para>
 
 	<screen>
-$ ./spout -a hello-world
-$ ./drain -a hello-world
+$ ./spout hello-world
+$ ./drain hello-world
 $
         </screen>
 
@@ -362,14 +362,14 @@ $
         <para><emphasis>First Window:</emphasis></para>
 
         <screen>
-$ ./drain -a hello-word -t 30
+$ ./drain -t 30 hello-word
         </screen>
         
 
         <para><emphasis>Second Window:</emphasis></para>
 
         <screen>
-$ ./spout -a hello-word
+$ ./spout hello-word
         </screen>
 
         <para>Once <command>spout</command> has sent a message, return
@@ -464,15 +464,15 @@ $ qpid-config add exchange topic news-se
         <para>Now we use drain to receive messages from <literal>news-service</literal> that match the subject <literal>sports</literal>.</para>
         <para><emphasis>First Window:</emphasis></para>
         <screen>
-$ ./drain -a news-service/sports -t 30
+$ ./drain -t 30 news-service/sports
         </screen>
 
         <para>In a second window, let's send messages to <literal>news-service</literal> using two different subjects:</para>
 
         <para><emphasis>Second Window:</emphasis></para>
         <screen>
-$ ./spout -a news-service/sports
-$ ./spout -a news-service/news
+$ ./spout news-service/sports
+$ ./spout news-service/news
         </screen>
 
         <para>Now look at the first window, the message with the
@@ -527,7 +527,7 @@ Message(properties={qpid.subject:sports,
 	    <para><emphasis>First Window:</emphasis></para>
 	
 	    <screen>
-$ ./drain -a news-service/*.news -t 30
+$ ./drain -t 30 news-service/*.news
 	    </screen>
 
 	    <para>Now let's send messages using several different
@@ -536,10 +536,10 @@ $ ./drain -a news-service/*.news -t 30
 	    <para><emphasis>Second Window:</emphasis></para>
 
 	    <screen>
-$ ./spout -a news-service/usa.news
-$ ./spout -a news-service/usa.sports
-$ ./spout -a news-service/europe.sports
-$ ./spout -a news-service/europe.news
+$ ./spout news-service/usa.news
+$ ./spout news-service/usa.sports
+$ ./spout news-service/europe.sports
+$ ./spout news-service/europe.news
 	    </screen>
 
 	    <para>In the first window, the messages with
@@ -559,7 +559,7 @@ Message(properties={qpid.subject:europe.
 	    <para><emphasis>First Window:</emphasis></para>
 
 	    <screen>
-$ ./drain -a news-service/#.news -t 30
+$ ./drain -t 30 news-service/#.news
 	    </screen>
 
 	    <para>In the second window, let's send messages using a
@@ -568,12 +568,12 @@ $ ./drain -a news-service/#.news -t 30
 	    <para><emphasis>Second Window:</emphasis></para>
 
 	    <screen>
-$ ./spout -a news-service/news
-$ ./spout -a news-service/sports
-$ ./spout -a news-service/usa.news
-$ ./spout -a news-service/usa.sports
-$ ./spout -a news-service/usa.faux.news
-$ ./spout -a news-service/usa.faux.sports
+$ ./spout news-service/news
+$ ./spout news-service/sports
+$ ./spout news-service/usa.news
+$ ./spout news-service/usa.sports
+$ ./spout news-service/usa.faux.news
+$ ./spout news-service/usa.faux.sports
 	    </screen>
 
         <para>In the first window, messages with
@@ -666,8 +666,8 @@ $ qpid-config add exchange topic my-topi
 	</para>
 
 	<screen>
-$ ./drain -a 'my-queue; {assert: always, node:{ type: queue }}'
-$ ./drain -a 'my-queue; {assert: always, node:{ type: topic }}'
+$ ./drain 'my-queue; {assert: always, node:{ type: queue }}'
+$ ./drain 'my-queue; {assert: always, node:{ type: topic }}'
 2010-04-20 17:30:46 warning Exception received from broker: not-found: not-found: Exchange not found: my-queue (../../src/qpid/broker/ExchangeRegistry.cpp:92) [caused by 2 \x07:\x01]
 Exchange my-queue does not exist
 	</screen>
@@ -683,8 +683,8 @@ Exchange my-queue does not exist
 	</para>
 
 	<screen>
-$ ./drain -a 'my-topic; {assert: always, node:{ type: topic }}'
-$ ./drain -a 'my-topic; {assert: always, node:{ type: queue }}'
+$ ./drain 'my-topic; {assert: always, node:{ type: topic }}'
+$ ./drain 'my-topic; {assert: always, node:{ type: queue }}'
 2010-04-20 17:31:01 warning Exception received from broker: not-found: not-found: Queue not found: my-topic (../../src/qpid/broker/SessionAdapter.cpp:754) [caused by 1 \x08:\x01]
 Queue my-topic does not exist
 	</screen>
@@ -698,7 +698,7 @@ Queue my-topic does not exist
 	<title>Creating a Queue Automatically</title>
 
 	<para><emphasis>First Window:</emphasis></para>
-	<screen>$ ./drain -a "xoxox ; {create: always}" -t 30</screen>
+	<screen>$ ./drain -t 30 "xoxox ; {create: always}"</screen>
 
 	<para>In previous examples, we created the queue before
 	listening for messages on it. Using <literal>create:
@@ -706,7 +706,7 @@ Queue my-topic does not exist
 	does not exist. Now we can send messages to this queue:</para>
 
 	<para><emphasis>Second Window:</emphasis></para>
-	<screen>$ ./spout -a "xoxox ; {create: always}"</screen>
+	<screen>$ ./spout "xoxox ; {create: always}"</screen>
 	
 	<para>Returning to the first window, we see that <command>drain</command> has received this message:</para>
 
@@ -732,14 +732,14 @@ Queue my-topic does not exist
           queue:
         </para>
         <screen>
-$ ./spout -a my-queue --content one
-$ ./spout -a my-queue --content two
-$ ./spout -a my-queue --content three
+$ ./spout my-queue --content one
+$ ./spout my-queue --content two
+$ ./spout my-queue --content three
         </screen>
         
         <para>Now we use drain to get those messages, using the browse option:</para>
         <screen>
-$ ./drain -a 'my-queue; {mode: browse}'
+$ ./drain 'my-queue; {mode: browse}'
 Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, content='one')
 Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, content='two')
 Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, content='three')
@@ -747,7 +747,7 @@ Message(properties={spout-id:ea75d64d-ea
         
         <para>We can confirm the messages are still on the queue by repeating the drain:</para>
         <screen>
-$ ./drain -a 'my-queue; {mode: browse}'
+$ ./drain 'my-queue; {mode: browse}'
 Message(properties={spout-id:fbb93f30-0e82-4b6d-8c1d-be60eb132530:0}, content='one')
 Message(properties={spout-id:ab9e7c31-19b0-4455-8976-34abe83edc5f:0}, content='two')
 Message(properties={spout-id:ea75d64d-ea37-47f9-96a9-d38e01c97925:0}, content='three')
@@ -1414,8 +1414,8 @@ declare variable $control external;
 	<para>The following shows the arguments used with <command>drain</command> to retrieve messages whose root element is named <literal>weather</literal>:</para>
 
 	<programlisting><![CDATA[
-$ ./drain -a "xml; {link:{x-bindings: [{exchange: xml, key:"weather", 
-arguments:{xquery:\"./weather\"}}]}}" -f 
+$ ./drain -f "xml; {link:{x-bindings: [{exchange: xml, key:"weather", 
+arguments:{xquery:\"./weather\"}}]}}"
  ]]></programlisting> 
       </example>
 



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org