aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-07-31 08:07:12 +0000
committerMike Buland <eichlan@xagasoft.com>2006-07-31 08:07:12 +0000
commit9139f1df4cda80b91ab68e5de27e85eaa4c54682 (patch)
tree87fadb2618ee8228f7184aa14bfa2b21741e3f49 /src
parent113fc467a7170a8a564049c64d1036dd10e6abac (diff)
downloadbuild-9139f1df4cda80b91ab68e5de27e85eaa4c54682.tar.gz
build-9139f1df4cda80b91ab68e5de27e85eaa4c54682.tar.bz2
build-9139f1df4cda80b91ab68e5de27e85eaa4c54682.tar.xz
build-9139f1df4cda80b91ab68e5de27e85eaa4c54682.zip
I still can't get the pymake file to auto-make the bison and flex .c files, but
besides that everything is looking great. There's only one thing left to parse and interpret before we can try actually building something.
Diffstat (limited to 'src')
-rw-r--r--src/action.cpp4
-rw-r--r--src/build.l2
-rw-r--r--src/build.y142
-rw-r--r--src/builder.cpp152
-rw-r--r--src/builder.h46
-rw-r--r--src/command.cpp3
-rw-r--r--src/filetarget.cpp17
-rw-r--r--src/filetarget.h19
-rw-r--r--src/main.cpp2
-rw-r--r--src/rule.cpp61
-rw-r--r--src/rule.h49
-rw-r--r--src/target.cpp24
-rw-r--r--src/target.h28
13 files changed, 522 insertions, 27 deletions
diff --git a/src/action.cpp b/src/action.cpp
index 7a7bbb8..c594792 100644
--- a/src/action.cpp
+++ b/src/action.cpp
@@ -25,9 +25,9 @@ void Action::add( Command *pCmd )
25void Action::debug() 25void Action::debug()
26{ 26{
27 if( bDefault ) 27 if( bDefault )
28 printf("action default:\n"); 28 printf(" action default:\n");
29 else 29 else
30 printf("action \"%s\":\n", sName.getString() ); 30 printf(" action \"%s\":\n", sName.getString() );
31 31
32 for( std::list<Command *>::iterator i = lCommand.begin(); 32 for( std::list<Command *>::iterator i = lCommand.begin();
33 i != lCommand.end(); i++ ) 33 i != lCommand.end(); i++ )
diff --git a/src/build.l b/src/build.l
index 3a457b1..a88f90d 100644
--- a/src/build.l
+++ b/src/build.l
@@ -58,7 +58,7 @@ std::string strbuf;
58 58
59"#".* /* single line comment */ 59"#".* /* single line comment */
60 60
61[^ \t\r\n\'\":=,.]+ { 61[^ \t\r\n\'\":=,/][^ \t\r\n\'\":=,]* {
62 yylval->strval = stringdup( yytext ); 62 yylval->strval = stringdup( yytext );
63 return STRING; 63 return STRING;
64} 64}
diff --git a/src/build.y b/src/build.y
index 45a84f1..8345b1f 100644
--- a/src/build.y
+++ b/src/build.y
@@ -4,6 +4,8 @@
4# include "builder.h" 4# include "builder.h"
5# include "action.h" 5# include "action.h"
6# include "command.h" 6# include "command.h"
7# include "rule.h"
8# include "filetarget.h"
7# include "build.tab.h" 9# include "build.tab.h"
8void yyerror( YYLTYPE *locp, Builder &bld, char const *msg ); 10void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
9%} 11%}
@@ -28,25 +30,25 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
28%token <strval> REGEXP "regular expression" 30%token <strval> REGEXP "regular expression"
29 31
30%token TOK_ADDSET "+=" 32%token TOK_ADDSET "+="
31%token TOK_DEFAULT "keyword 'default'" 33%token TOK_DEFAULT "default"
32%token TOK_ACTION "keyword 'action'" 34%token TOK_ACTION "action"
33%token TOK_CREATE "keyword 'create'" 35%token TOK_CREATE "create"
34%token TOK_FILE "keyword 'file'" 36%token TOK_FILE "file"
35%token TOK_FROM "keyword 'from'" 37%token TOK_FROM "from"
36%token TOK_FILES "keyword 'files'" 38%token TOK_FILES "files"
37%token TOK_IN "keyword 'in'" 39%token TOK_IN "in"
38%token TOK_USING "keyword 'using'" 40%token TOK_USING "using"
39%token TOK_RULE "keyword 'rule'" 41%token TOK_RULE "rule"
40%token TOK_REQUIRES "keyword 'requires'" 42%token TOK_REQUIRES "requires"
41%token TOK_FOR "keyword 'for'" 43%token TOK_FOR "for"
42%token TOK_SET "keyword 'set'" 44%token TOK_SET "set"
43%token TOK_MATCHES "keyword 'matches'" 45%token TOK_MATCHES "matches"
44%token TOK_ALL "keyword 'all'" 46%token TOK_ALL "all"
45%token TOK_ONE "keyword 'one'" 47%token TOK_ONE "one"
46%token TOK_PERFORM "keyword 'perform'" 48%token TOK_PERFORM "perform"
47%token TOK_PRODUCES "keyword 'produces'" 49%token TOK_PRODUCES "produces"
48%token TOK_COMMAND "keyword 'command'" 50%token TOK_COMMAND "command"
49%token TOK_CHECK "keyword 'check'" 51%token TOK_CHECK "check"
50%token TOK_EOL "end of line" 52%token TOK_EOL "end of line"
51%token ',' ':' '=' 53%token ',' ':' '='
52 54
@@ -73,9 +75,40 @@ line: TOK_DEFAULT TOK_ACTION ':'
73 } 75 }
74 actionlst 76 actionlst
75 | TOK_CREATE createwhat TOK_FROM createfrom TOK_USING createusing 77 | TOK_CREATE createwhat TOK_FROM createfrom TOK_USING createusing
78 | STRING TOK_REQUIRES
79 {
80 bld.setTmp( $1 );
81 }
82 reqlst
83 | listcmds
84 | TOK_FOR STRING
85 {
86 bld.setContext( $2 );
87 }
88 listcmds
89 {
90 bld.setContext();
91 }
92 | rule
76 ; 93 ;
77 94
78createwhat: TOK_FILE STRING { printf("target: %s\n", $2 ); } 95reqlst: STRING
96 {
97 bld.requires( bld.getTmp(), $1 );
98 }
99 | reqlst ',' STRING
100 {
101 bld.requires( bld.getTmp(), $3 );
102 }
103 ;
104
105listcmds: TOK_SET setexpr
106 ;
107
108createwhat: TOK_FILE STRING
109 {
110 bld.add( new FileTarget( $2 ) );
111 }
79 ; 112 ;
80 113
81createfrom: TOK_FILES TOK_IN createfromdirlst 114createfrom: TOK_FILES TOK_IN createfromdirlst
@@ -88,7 +121,10 @@ createfromdirlst: createfromdir
88createfromdir: STRING { printf(" srcdir: %s\n", $1 ); } 121createfromdir: STRING { printf(" srcdir: %s\n", $1 ); }
89 ; 122 ;
90 123
91createusing: TOK_RULE STRING { printf(" rule: %s\n", $2 ); } 124createusing: TOK_RULE STRING
125 {
126 bld.lastTarget()->setRule( $2 );
127 }
92 ; 128 ;
93 129
94actionlst: action 130actionlst: action
@@ -101,6 +137,70 @@ action: TOK_CHECK STRING
101 } 137 }
102 ; 138 ;
103 139
140setexpr: STRING '=' STRING
141 {
142 bld.varSet( $1, $3 );
143 }
144 | STRING TOK_ADDSET STRING
145 {
146 bld.varAddSet( $1, $3 );
147 }
148 ;
149
150rule: TOK_RULE STRING
151 {
152 bld.add( new Rule( $2 ) );
153 }
154 rulesublst TOK_PERFORM rulecompletion
155 ;
156
157rulesublst: rulesub
158 | rulesublst rulesub
159 ;
160
161rulesub: TOK_MATCHES rulematches
162 | TOK_PRODUCES STRING
163 {
164 bld.lastRule()->setProduces( $2 );
165 }
166 ;
167
168rulematches: TOK_ALL REGEXP
169 {
170 try
171 {
172 bld.lastRule()->setMatches( Rule::matchAll, $2 );
173 }
174 catch( BuildException &e )
175 {
176 std::string s("RegExp compile error: ");
177 s += e.what();
178 yyerror( &yyloc, bld, s.c_str() );
179 return 1;
180 }
181 }
182 | TOK_ONE REGEXP
183 {
184 try
185 {
186 bld.lastRule()->setMatches( Rule::matchOne, $2 );
187 }
188 catch( BuildException &e )
189 {
190 std::string s("RegExp compile error: ");
191 s += e.what();
192 yyerror( &yyloc, bld, s.c_str() );
193 return 1;
194 }
195 }
196 ;
197
198rulecompletion: TOK_COMMAND STRING
199 {
200 bld.lastRule()->setPerforms( Rule::perfCommand, $2 );
201 }
202 ;
203
104%% 204%%
105 205
106void yyerror( YYLTYPE *locp, Builder &bld, char const *msg ) 206void yyerror( YYLTYPE *locp, Builder &bld, char const *msg )
diff --git a/src/builder.cpp b/src/builder.cpp
index 2de6f5c..e5017e2 100644
--- a/src/builder.cpp
+++ b/src/builder.cpp
@@ -3,13 +3,17 @@
3#include "builder.h" 3#include "builder.h"
4#include "action.h" 4#include "action.h"
5#include "command.h" 5#include "command.h"
6#include "target.h"
6#include "build.tab.h" 7#include "build.tab.h"
8#include "rule.h"
7 9
8subExceptionDef( BuildException ) 10subExceptionDef( BuildException )
9 11
10Builder::Builder() : 12Builder::Builder() :
11 pDefaultAction( NULL ), 13 pDefaultAction( NULL ),
12 pLastAddedAction( NULL ) 14 pLastAddedAction( NULL ),
15 sTmp(""),
16 sContext("")
13{ 17{
14} 18}
15 19
@@ -51,13 +55,159 @@ void Builder::add( Command *pCmd )
51 } 55 }
52} 56}
53 57
58void Builder::add( Rule *pRule )
59{
60 pLastAddedRule = pRule;
61 mRule[pRule->getName()] = pRule;
62}
63
64void Builder::add( Target *pTarg )
65{
66 pLastAddedTarget = pTarg;
67 mTarget[pTarg->getName()] = pTarg;
68}
69
54void Builder::debug() 70void Builder::debug()
55{ 71{
72 printf("Actions:\n");
56 pDefaultAction->debug(); 73 pDefaultAction->debug();
57 for( std::map<const char *, Action *, ltstr>::iterator i = mAction.begin(); 74 for( std::map<const char *, Action *, ltstr>::iterator i = mAction.begin();
58 i != mAction.end(); i++ ) 75 i != mAction.end(); i++ )
59 { 76 {
60 (*i).second->debug(); 77 (*i).second->debug();
61 } 78 }
79
80 printf("Targets:\n");
81 for( std::map<const char *, Target *, ltstr>::iterator i = mTarget.begin();
82 i != mTarget.end(); i++ )
83 {
84 (*i).second->debug();
85 }
86
87 printf("Rules:\n");
88 for( std::map<const char *, Rule *, ltstr>::iterator i = mRule.begin();
89 i != mRule.end(); i++ )
90 {
91 (*i).second->debug();
92 }
93
94 printf("Variables:\n");
95 for( varmap::iterator i = mVar.begin(); i != mVar.end(); i++ )
96 {
97 printf(" %s = \"%s\"\n", (*i).first.c_str(), (*i).second.c_str() );
98 }
99
100 printf("Variables (by context):\n");
101 for( std::map<std::string, varmap>::iterator j = mContVar.begin();
102 j != mContVar.end(); j++ )
103 {
104 printf(" %s:\n", (*j).first.c_str() );
105 for( varmap::iterator i = (*j).second.begin();
106 i != (*j).second.end(); i++ )
107 {
108 printf(" %s = \"%s\"\n",
109 (*i).first.c_str(), (*i).second.c_str() );
110 }
111 }
112
113 printf("Additional dependancies:\n");
114 for( std::map<std::string, std::list<std::string> *>::iterator i =
115 mRequires.begin(); i != mRequires.end(); i++ )
116 {
117 printf(" %s: ", (*i).first.c_str() );
118 std::list<std::string> *pList = (*i).second;
119 for( std::list<std::string>::iterator j = pList->begin();
120 j != pList->end(); j++ )
121 {
122 if( j != pList->begin() )
123 printf(", ");
124 printf("%s", (*j).c_str() );
125 }
126 printf("\n");
127 }
128}
129
130void Builder::checkVar( const char *cont, const char *sName )
131{
132 if( cont[0] != '\0' )
133 {
134 varmap &mmVar = mContVar[cont];
135 if( mmVar.find( sName ) == mmVar.end() )
136 {
137 checkVar( "", sName );
138 mmVar[sName] = mVar[sName];
139 }
140 }
141 else
142 {
143 if( mVar.find( sName ) == mVar.end() )
144 {
145 char *env = getenv( sName );
146 if( env )
147 mVar[sName] = env;
148 else
149 mVar[sName] = "";
150 }
151 }
152}
153
154void Builder::varSet( const char *sName, const char *sValue )
155{
156 checkVar( sContext, sName );
157
158 if( sContext[0] == '\0' )
159 {
160 mVar[sName] = sValue;
161 }
162 else
163 {
164 mContVar[sContext.getString()][sName] = sValue;
165 }
166}
167
168void Builder::varAddSet( const char *sName, const char *sValue )
169{
170 checkVar( sContext, sName );
171
172 if( sContext[0] == '\0' )
173 {
174 std::string s = mVar[sName];
175 s += " ";
176 s += sValue;
177 mVar[sName] = s;
178 }
179 else
180 {
181 std::string s = mContVar[sContext.getString()][sName];
182 s += " ";
183 s += sValue;
184 mContVar[sContext.getString()][sName] = s;
185 }
186}
187
188void Builder::requires( const char *sBase, const char *sReq )
189{
190 std::list<std::string> *pList = NULL;
191 if( mRequires.find(sBase) == mRequires.end() )
192 {
193 pList = new std::list<std::string>;
194 mRequires[sBase] = pList;
195 }
196 else
197 {
198 pList = mRequires[sBase];
199 }
200
201 pList->push_back( sReq );
202}
203
204void Builder::setContext( const char *sCont )
205{
206 sContext = sCont;
207}
208
209void Builder::setContext()
210{
211 setContext("");
62} 212}
63 213
diff --git a/src/builder.h b/src/builder.h
index 58afaf5..89810c0 100644
--- a/src/builder.h
+++ b/src/builder.h
@@ -6,12 +6,15 @@
6#include <map> 6#include <map>
7#include "build.tab.h" 7#include "build.tab.h"
8#include "exceptionbase.h" 8#include "exceptionbase.h"
9#include "staticstring.h"
9 10
10subExceptionDecl( BuildException ) 11subExceptionDecl( BuildException )
11 12
12class Builder; 13class Builder;
13class Action; 14class Action;
14class Command; 15class Command;
16class Rule;
17class Target;
15 18
16#define YY_DECL int yylex( YYSTYPE *yylval_param, YYLTYPE *yylloc_param, Builder &bld ) 19#define YY_DECL int yylex( YYSTYPE *yylval_param, YYLTYPE *yylloc_param, Builder &bld )
17YY_DECL; 20YY_DECL;
@@ -39,6 +42,13 @@ public:
39 42
40 void add( Action *pAct ); 43 void add( Action *pAct );
41 void add( Command *pCmd ); 44 void add( Command *pCmd );
45 void add( Rule *pRule );
46 void add( Target *pTarg );
47 void varSet( const char *sName, const char *sValue );
48 void varAddSet( const char *sName, const char *sValue );
49 void requires( const char *sBase, const char *sReq );
50 void setContext( const char *sCont );
51 void setContext();
42 52
43 bool hasDefaultAction() 53 bool hasDefaultAction()
44 { 54 {
@@ -47,13 +57,49 @@ public:
47 57
48 void debug(); 58 void debug();
49 59
60 Rule *lastRule()
61 {
62 return pLastAddedRule;
63 }
64
65 Target *lastTarget()
66 {
67 return pLastAddedTarget;
68 }
69
70 void setTmp( const char *s )
71 {
72 sTmp = s;
73 }
74
75 const char *getTmp()
76 {
77 return sTmp;
78 }
79
50private: 80private:
81 void checkVar( const char *cont, const char *sName );
51 void scanBegin(); 82 void scanBegin();
52 void scanEnd(); 83 void scanEnd();
53 84
54 Action *pDefaultAction; 85 Action *pDefaultAction;
55 Action *pLastAddedAction; 86 Action *pLastAddedAction;
56 std::map<const char *, Action *, ltstr> mAction; 87 std::map<const char *, Action *, ltstr> mAction;
88
89 Rule *pLastAddedRule;
90 std::map<const char *, Rule *, ltstr> mRule;
91
92 Target *pLastAddedTarget;
93 std::map<const char *, Target *, ltstr> mTarget;
94
95 typedef std::map<std::string, std::string> varmap;
96 varmap mVar;
97 std::map<std::string, std::list<std::string> *> mRequires;
98
99 std::map<std::string, varmap> mContVar;
100 StaticString sContext;
101
102 StaticString sTmp;
57}; 103};
58 104
59#endif 105#endif
diff --git a/src/command.cpp b/src/command.cpp
index 4a1fa6c..72f9a4c 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -13,7 +13,6 @@ Command::~Command()
13void Command::debug() 13void Command::debug()
14{ 14{
15 static const char *cmdt[]={"Check", "Clean"}; 15 static const char *cmdt[]={"Check", "Clean"};
16 printf(" command: %s %s\n", cmdt[ nType ], sTarget.getString() ); 16 printf(" command: %s %s\n", cmdt[ nType ], sTarget.getString() );
17
18} 17}
19 18
diff --git a/src/filetarget.cpp b/src/filetarget.cpp
new file mode 100644
index 0000000..b9d7946
--- /dev/null
+++ b/src/filetarget.cpp
@@ -0,0 +1,17 @@
1#include "filetarget.h"
2
3FileTarget::FileTarget( const char *sName ) :
4 Target( sName )
5{
6}
7
8FileTarget::~FileTarget()
9{
10}
11
12void FileTarget::debug()
13{
14 Target::debug();
15 printf(" type: FileTarget\n");
16}
17
diff --git a/src/filetarget.h b/src/filetarget.h
new file mode 100644
index 0000000..cf4b3d6
--- /dev/null
+++ b/src/filetarget.h
@@ -0,0 +1,19 @@
1#ifndef FILE_TARGET_H
2#define FILE_TARGET_H
3
4#include <stdint.h>
5#include "target.h"
6
7class FileTarget : public Target
8{
9public:
10 FileTarget( const char *sName );
11 virtual ~FileTarget();
12
13 virtual void debug();
14
15private:
16
17};
18
19#endif
diff --git a/src/main.cpp b/src/main.cpp
index 598a97f..995009d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6,6 +6,8 @@ int main()
6 6
7 bld.load("congo"); 7 bld.load("congo");
8 8
9 printf("\n\n----------\nDebug dump\n----------\n");
10
9 bld.debug(); 11 bld.debug();
10} 12}
11 13
diff --git a/src/rule.cpp b/src/rule.cpp
new file mode 100644
index 0000000..a7ebf9b
--- /dev/null
+++ b/src/rule.cpp
@@ -0,0 +1,61 @@
1#include "rule.h"
2#include "builder.h" // for BuildException
3
4Rule::Rule( const char *sName ) :
5 sName( sName ),
6 sProduces("{target}")
7{
8}
9
10Rule::~Rule()
11{
12 regfree( &rWhat );
13}
14
15void Rule::debug()
16{
17 printf(" Rule %s produces %s:\n",
18 sName.getString(),
19 sProduces.getString()
20 );
21 printf(" Matches ");
22 if( mHow == matchOne )
23 printf("one ");
24 else if( mHow == matchAll )
25 printf("all ");
26 printf("/%s/\n", sWhat.getString() );
27
28 printf(" Performs ");
29 if( pHow == perfCommand )
30 printf("command ");
31 printf("\"%s\"\n", sPerfCmd.getString() );
32}
33
34void Rule::setProduces( const char *sP )
35{
36 sProduces = sP;
37}
38
39void Rule::setMatches( Matches how, const char *sW )
40{
41 sWhat = sW;
42 mHow = how;
43
44 int nErr = regcomp( &rWhat, sW, REG_EXTENDED|REG_NEWLINE );
45 if( nErr )
46 {
47 size_t length = regerror( nErr, &rWhat, NULL, 0 );
48 char *buffer = new char[length];
49 (void) regerror( nErr, &rWhat, buffer, length );
50 StaticString s( buffer );
51 delete[] buffer;
52 throw BuildException( s.getString() );
53 }
54}
55
56void Rule::setPerforms( Perform pwhat, const char *sperfcmd )
57{
58 pHow = pwhat;
59 sPerfCmd = sperfcmd;
60}
61
diff --git a/src/rule.h b/src/rule.h
new file mode 100644
index 0000000..64cdc9d
--- /dev/null
+++ b/src/rule.h
@@ -0,0 +1,49 @@
1#ifndef RULE_H
2#define RULE_H
3
4#include <stdint.h>
5#include <regex.h>
6#include "staticstring.h"
7
8class Rule
9{
10public:
11 enum Matches
12 {
13 matchOne,
14 matchAll
15 };
16
17 enum Perform
18 {
19 perfCommand
20 };
21
22public:
23 Rule( const char *sName );
24 virtual ~Rule();
25
26 const char *getName()
27 {
28 return sName;
29 }
30
31 void debug();
32
33 void setProduces( const char *sProduces );
34 void setMatches( Matches how, const char *sWhat );
35 void setPerforms( Perform pwhat, const char *sPerfCmd );
36
37private:
38 StaticString sName;
39 StaticString sProduces;
40
41 Matches mHow;
42 StaticString sWhat;
43 regex_t rWhat;
44
45 Perform pHow;
46 StaticString sPerfCmd;
47};
48
49#endif
diff --git a/src/target.cpp b/src/target.cpp
new file mode 100644
index 0000000..b0967bf
--- /dev/null
+++ b/src/target.cpp
@@ -0,0 +1,24 @@
1#include "target.h"
2
3Target::Target( const char *sName ) :
4 sName( sName )
5{
6}
7
8Target::~Target()
9{
10}
11
12void Target::setRule( const char *sRule )
13{
14 this->sRule = sRule;
15}
16
17void Target::debug()
18{
19 printf(" %s:\n Rule: %s\n",
20 sName.getString(),
21 sRule.getString()
22 );
23}
24
diff --git a/src/target.h b/src/target.h
new file mode 100644
index 0000000..667c467
--- /dev/null
+++ b/src/target.h
@@ -0,0 +1,28 @@
1#ifndef TARGET_H
2#define TARGET_H
3
4#include <stdint.h>
5#include "staticstring.h"
6
7class Target
8{
9public:
10 Target( const char *sName );
11 virtual ~Target();
12
13 const char *getName()
14 {
15 return sName;
16 }
17
18 void setRule( const char *sRule );
19
20 virtual void debug();
21
22private:
23 StaticString sName;
24 StaticString sRule;
25
26};
27
28#endif