aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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