aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..142927d
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,255 @@
1#include "buildparser.h"
2#include "context.h"
3#include "ast.h"
4#include "runner.h"
5#include "target.h"
6
7#include "viewplugger.h"
8
9#include <bu/optparser.h>
10#include <bu/sio.h>
11#include <sys/types.h>
12#include <dirent.h>
13#include <stdlib.h>
14#include <unistd.h>
15
16extern char **environ;
17
18using namespace Bu;
19
20class Options : public Bu::OptParser
21{
22public:
23 Options( int argc, char *argv[] ) :
24 sView("default"),
25 sAction("default"),
26 sConfig("default.bld"),
27 bDot( false ),
28 bDebug( false ),
29 bAutoInclude( true ),
30 bAstDump( false ),
31 bEnviron( true ),
32 iInfoLevel( 0 )
33 {
34 bool bClean = false;
35 addHelpBanner("build mark 3\n");
36
37 Bu::FString sViews("Select a view from: ");
38 StrList lViews = ViewPlugger::getInstance().getPluginList();
39 for( StrList::iterator i = lViews.begin(); i; i++ )
40 {
41 if( i != lViews.begin() )
42 sViews += ", ";
43 sViews += *i;
44 }
45
46 addHelpBanner("The following options do things other than build:");
47 addOption( iInfoLevel, 'i', "info", "Display some basic info about the "
48 "loaded build config, including available targets.");
49
50 addHelpBanner("The following options control general execution:");
51 addOption( sView, 'v', "view", sViews );
52 addOption( sConfig, 'f', "file", "Select a different config file." );
53 addOption( bClean, 'c', "Shorthand for running action 'clean'. If an "
54 "action is specified, this will modify it to run 'clean-action'.");
55 addOption( slot(this, &Options::onChdir), 'C', "chdir",
56 "Change to directory before doing anything else.");
57
58 addHelpBanner("\nThe following options control debugging:");
59 addOption( bEnviron, "no-env", "Do not import environment variables.");
60 addOption( bDot, "dot", "Generate a dot chart after execution." );
61 addOption( bDebug, "debug",
62 "Dump massive amounts of hard to read debugging data." );
63 addOption( bAstDump, "debug-ast",
64 "Display the raw AST that is computed from parsing the input. "
65 "You should probably never ever use this, it'll scare you."
66 );
67
68 setOverride( "no-env", "false" );
69 setOverride( "dot", "true" );
70 setOverride( "debug", "true" );
71 setOverride( "debug-ast", "true" );
72 setOverride( "info", "1" );
73 setOverride( 'c', "true" );
74
75 addHelpOption();
76
77 setNonOption( slot( this, &Options::onNonOption ) );
78
79 parse( argc, argv );
80
81 if( bClean )
82 {
83 if( sAction == "default" )
84 sAction = "clean";
85 else
86 sAction.prepend("clean-");
87 }
88 }
89
90 virtual ~Options()
91 {
92 }
93
94 int onChdir( StrArray sParams )
95 {
96 if( sParams.getSize() == 0 )
97 {
98 sio << "You must specify a directory name!" << sio.nl << sio.nl;
99 exit(2);
100 }
101 chdir( sParams[1].getStr() );
102 return 1;
103 }
104
105 int onNonOption( StrArray sParams )
106 {
107 sAction = sParams[0];
108 return 0;
109 }
110
111 Bu::FString sView;
112 Bu::FString sAction;
113 Bu::FString sConfig;
114 bool bDot;
115 bool bDebug;
116 bool bAutoInclude;
117 bool bAstDump;
118 bool bEnviron;
119 int iInfoLevel;
120};
121
122int main( int argc, char *argv[] )
123{
124 typedef Bu::List<Bu::FString> StrList;
125 StrList lShareList;
126 lShareList.append("/usr/share/build/").append("./share/");
127 Ast ast;
128 Context cnt;
129 BuildParser bp( ast );
130
131 for( StrList::iterator i = lShareList.begin(); i; i++ )
132 {
133 bp.addIncludePath( *i + "include");
134 }
135
136 Options opts( argc, argv );
137
138 try
139 {
140 cnt.setView( ViewPlugger::getInstance().instantiate( opts.sView ) );
141 }
142 catch( Bu::HashException &e )
143 {
144 sio << "Error: Invalid view specified, please choose from the "
145 "following choices:" << sio.nl << sio.nl << "\t";
146
147 StrList lViews = ViewPlugger::getInstance().getPluginList();
148 for( StrList::iterator i = lViews.begin(); i; i++ )
149 {
150 if( i != lViews.begin() )
151 sio << ", ";
152 sio << *i;
153 }
154 sio << sio.nl << sio.nl;
155 return 1;
156 }
157
158 // Load up the environment as vars.
159 if( opts.bEnviron )
160 {
161 for( char **env = environ; *env; env++ )
162 {
163 int iSplit;
164 for( iSplit = 0; (*env)[iSplit] != '='; iSplit++ ) { }
165 cnt.addVariable(
166 FString( *env, iSplit ),
167 FString( *env+iSplit+1 )
168 );
169 }
170 }
171
172 if( opts.bAutoInclude )
173 {
174 DIR *d;
175 Bu::FString sAutoDir;
176 for( StrList::iterator i = lShareList.begin(); i; i++ )
177 {
178 sAutoDir = *i + "autoinclude";
179 d = opendir( sAutoDir.getStr() );
180 if( d )
181 break;
182 }
183 if( !d )
184 {
185 cnt.getView()->sysWarning(
186 "Could not find an autoinclude directory."
187 );
188 }
189 else
190 {
191 struct dirent *de;
192 while( (de = readdir( d )) )
193 {
194 if( de->d_name[0] == '.' || (de->d_type != DT_REG) )
195 continue;
196 //sio << "Auto-including: " << de->d_name << sio.nl;
197 bp.load( sAutoDir + "/" + de->d_name );
198 }
199 }
200 }
201
202 bp.load( opts.sConfig );
203
204 if( opts.bAstDump )
205 {
206 sio << ast << sio.nl << sio.nl;
207 return 0;
208 }
209
210// sio << ast << sio.nl;
211
212 Runner r( ast, cnt );
213 r.initialize();
214
215 r.run();
216
217 switch( opts.iInfoLevel )
218 {
219 case 0:
220 // Do nothing
221 break;
222
223 case 1:
224 cnt.printBasicInfo();
225 return 0;
226 }
227
228 try
229 {
230 r.execAction( opts.sAction );
231 }
232 catch( std::exception &e )
233 {
234 cnt.getView()->sysError(e.what());
235 }
236 catch( ... )
237 {
238 cnt.getView()->sysError(
239 "Unknown error occured, this is probably bad..."
240 );
241 }
242
243 if( opts.bDot )
244 {
245 cnt.writeTargetDot();
246 }
247
248 if( opts.bDebug )
249 {
250 sio << "Final context:" << sio.nl << cnt << sio.nl << sio.nl;
251 }
252
253 return 0;
254}
255