00001 /* 00002 * @file main.cpp 00003 * @author Reshen Amin <reshen@zensrc.com> 00004 * 00005 * @brief Main Entry point for Byzantine Generals Coding Sample 00006 * 00007 * @license Byzantine Generals Problem Coding Sample.<br> 00008 * Copyright (C) 2010 Reshen Amin.<br> 00009 * See @ref license_sec for details.<br> 00010 */ 00011 00012 /*! \mainpage Byzantine Generals Coding Sample 00013 * 00014 * @author Reshen Amin <reshen@zensrc.com> 00015 * 00016 * 00017 * \section note_sec General Notes 00018 * 00019 * - A digital copy of the source code for this coding sample is available under 00020 * version control at <http://bitbucket.org/reshen/byzantine_generals/src>. 00021 * 00022 * - Generally speaking, the Google C++ Style Guide was used for this coding 00023 * sample, it is available at 00024 * <http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>. 00025 * 00026 * - The source code has been marked up with Doxygen style commenting, which can 00027 * make for much easier navigation. The generated doxygen output can be viewed 00028 * at <http://zensrc.com/byzgen_doxygen/html/index.html> 00029 * 00030 * 00031 * \section intro_sec Byzantine Generals Introduction 00032 * 00033 * This simple program demonstrates the Byzantine Generals Problem in which 00034 * multiple generals of the Byzantine Empire's army need to coordinate to attack 00035 * or retreat from a city. They believe that either some of the other Generals 00036 * or their Messengers are traitors and may corrupt Orders passed between them, 00037 * yet they still need to coordinate to all come to the same course of action. 00038 * 00039 * For a good synopsis of the problem, see either Wikipedia 00040 * <http://en.wikipedia.org/wiki/Byzantine_generals> or 00041 * Byzantine Generals Problem by Mark Nelson at 00042 * <http://marknelson.us/2007/07/23/byzantine/>. 00043 * 00044 * For a solution to exist, we must: 00045 * 00046 * -# Terminate - all loyal generals need to reach a decision regarding the 00047 * orders they've been given. 00048 * -# Agree - all loyal generals have to agree on the decision they are making. 00049 * -# Valid - all loyal generals have to agree on the value they have been 00050 * given by their commanding general if and only if the commanding general 00051 * is loyal. 00052 * 00053 * 00054 * \section build_dep_sec Build Dependencies 00055 * 00056 * -# a2ps / ps2pdf - for printing of source code 00057 * -# Boost 00058 * -# cppcheck - for static analysis of code during compilation 00059 * -# Doxygen - for doxygen documentation 00060 * -# etags - for TAGS generation over source code 00061 * -# GNU Make 00062 * -# GNU poject C++ compiler 00063 * -# Graphviz / dot - for graph generation 00064 * -# Log4cpp 00065 * -# Valgrind - for memory self tests 00066 * 00067 * 00068 * \section build_targets_sec Build Targets 00069 * 00070 * See 'make help' for latest target options. 00071 * 00072 * \section usage_sec Example Usage 00073 * 00074 * The following example demonstrates 5 loyal generals and 2 disloyal generals. 00075 * 00076 * \verbinclude tree.txt 00077 * 00078 * The graph below shows the output from General #1's communication tree. As 00079 * each message is received, it is added to the tree using the communication 00080 * path contained therein. The communication path is simply an ordered list of 00081 * each General who touched that particular message. The second line, labeled 00082 * Rx, shows what the order was when the message was received. The third line, 00083 * labeled Vote, is a majority vote of all of the node's childrens' Rx fields. 00084 * Each level in the tree represents all of the messages sent during that round 00085 * of communication. Nodes that are colored pink are messages that have passed 00086 * through at least one disloyal general. The white nodes should always 00087 * outnumber the pink nodes, indicating that despite the disloyal generals best 00088 * efforts, a deterministic outcome is always possible. 00089 * 00090 * <center> 00091 * \dotfile tree.dot 00092 * [ <a href="tree.pdf">PDF</a> ] 00093 * </center> 00094 * 00095 * \section license_sec License 00096 * 00097 * Byzantine Generals Problem Coding Sample<br> 00098 * Copyright (C) 2010 Reshen Amin<br> 00099 * 00100 * This program is free software: you can redistribute it and/or modify 00101 * it under the terms of the GNU General Public License as published by 00102 * the Free Software Foundation, version 3 of the License. 00103 * 00104 * This program is distributed in the hope that it will be useful, 00105 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00106 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00107 * GNU General Public License for more details. 00108 * 00109 * You should have received a copy of the GNU General Public License 00110 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00111 * 00112 */ 00113 00114 /* Order of includes is always <current_file>.h, C library, C++ library, 00115 * other libraries' .h, project's .h */ 00116 00117 #include <stdio.h> 00118 00119 #include <exception> 00120 00121 #include "clihandler.h" 00122 00123 int main(int argc, char* argv[]) { 00124 printf("Byzantine Generals Problem Coding Sample\n" 00125 "Copyright (C) 2010 Reshen Amin <reshen@zensrc.com>\n" 00126 "This program comes with ABSOLUTELY NO WARRANTY; This is free\n" 00127 "software, and you are welcome to redistribute it under certain\n" 00128 "conditions; See the GNU General Public License for more\n" 00129 "details.\n\n"); 00130 00131 ByzGeneralsReturnCodes::type result = ByzGeneralsReturnCodes::kNoError; 00132 00133 try { 00134 CLIHandler handler; 00135 result = handler.Exec(argc, argv); 00136 } 00137 catch(const std::invalid_argument& e) { 00138 fprintf(stderr, "Invalid argument error: %s\n" 00139 "Try `%s --help` for more information", e.what(), argv[0]); 00140 00141 result = ByzGeneralsReturnCodes::kInvalidInput; 00142 } 00143 catch(const std::exception& e) { 00144 fprintf(stderr, "Exception: %s\n", e.what()); 00145 00146 result = ByzGeneralsReturnCodes::kUnknown; 00147 } 00148 catch(...) { 00149 fprintf(stderr, "Exception of unknown type!"); 00150 00151 result = ByzGeneralsReturnCodes::kUnknown; 00152 } 00153 00154 return result; 00155 } 00156
1.6.3