1 /**
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions are
4 * met :
5 *
6 * . Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 *
9 * . Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * . The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 package cppstyle;
30
31 import java.io.FileInputStream;
32 import java.io.FileNotFoundException;
33 import cppast.VisitorComposite;
34 import cppstyle.checks.FileHeaderCheck;
35 import cpptools.Analyzer;
36 import cpptools.ConsoleLogger;
37 import cpptools.EventHandler;
38 import cpptools.FileObserverComposite;
39 import cpptools.Options;
40 import cpptools.Usage;
41
42 /**
43 * Provides style checking for C++.
44 *
45 * @author Mathieu Champlon
46 */
47 public final class CppStyle
48 {
49 private final VisitorComposite visitors = new VisitorComposite();
50 private final FileObserverComposite observers = new FileObserverComposite();
51 private final Analyzer analyzer;
52
53 /**
54 * Create a CppStyle instance.
55 *
56 * @param options the options
57 * @param handler the log handler
58 * @throws FileNotFoundException the configuration file cannot be found
59 */
60 public CppStyle( final Options options, final EventHandler handler ) throws FileNotFoundException
61 {
62 if( !options.hasOption( "c" ) )
63 throw new IllegalArgumentException( "missing mandatory 'c' option" );
64 analyzer = new Analyzer( options, visitors, observers, handler );
65 populate( visitors, options.getOptionPropertyValues( "c" ).get( 0 ) );
66 }
67
68 private void populate( final VisitorComposite visitors, final String filename ) throws FileNotFoundException
69 {
70 visitors.register( new FileHeaderCheck( new FileInputStream( filename ) ) );
71 }
72
73 /**
74 * Run the analyzis.
75 */
76 public void run()
77 {
78 analyzer.run();
79 }
80
81 /**
82 * Run the application.
83 *
84 * @param args the arguments
85 * @throws FileNotFoundException the configuration file cannot be found
86 */
87 public static void main( final String[] args ) throws FileNotFoundException
88 {
89 if( !check( args ) )
90 return;
91 final Options options = new Options( args );
92 new CppStyle( options, new ConsoleLogger( options ) ).run();
93 }
94
95 private static boolean check( final String[] args )
96 {
97 if( args.length > 0 && !args[0].equals( "-h" ) )
98 return true;
99 usage();
100 return false;
101 }
102
103 private static void usage()
104 {
105 final Usage usage = new Usage( "cppstyle", "http://cppncss.sourceforge.net", "1.0.0" );
106 usage.addOption( "h", "print this message" );
107 usage.addOption( "d", "print debugging information" );
108 usage.addOption( "v", "be extra verbose" );
109 usage.addOption( "k", "keep going on parsing errors" );
110 usage.addOption( "r", "process directories recursively" );
111 usage.addOption( "x", "output result as xml" );
112 usage.addOption( "c=<file>", "use the given configuration file" );
113 usage.addOption( "f=<file>", "output result to the given file" );
114 usage.addOption( "D<symbol>[=[<value>]]", "replace define <symbol> with <value>" );
115 usage.addOption( "M<symbol>[=[<value>]]", "replace macro <symbol> with <value>" );
116 usage.addOption( "p=<path>", "remove <path> prefix when displaying file names" );
117 usage.display();
118 }
119 }