aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/action.cpp15
-rw-r--r--src/action.h2
-rw-r--r--src/build.l24
-rw-r--r--src/build.y77
-rw-r--r--src/builder.cpp263
-rw-r--r--src/builder.h28
-rw-r--r--src/main.cpp14
-rw-r--r--src/regexp.cpp13
-rw-r--r--src/viewerplain.cpp5
-rw-r--r--src/viewerplain.h1
10 files changed, 399 insertions, 43 deletions
diff --git a/src/action.cpp b/src/action.cpp
index 8907816..51868eb 100644
--- a/src/action.cpp
+++ b/src/action.cpp
@@ -23,6 +23,11 @@ void Action::add( Command *pCmd )
23 lCommand.push_back( pCmd ); 23 lCommand.push_back( pCmd );
24} 24}
25 25
26void Action::add( int nType, const char *sCmd )
27{
28 lRegExCommand.push_back( std::pair<int,std::string>( nType, sCmd ) );
29}
30
26void Action::debug() 31void Action::debug()
27{ 32{
28 if( bDefault ) 33 if( bDefault )
@@ -39,6 +44,16 @@ void Action::debug()
39 44
40void Action::execute( Builder &bld ) 45void Action::execute( Builder &bld )
41{ 46{
47 for( std::list<std::pair<int,std::string> >::iterator i =
48 lRegExCommand.begin(); i != lRegExCommand.end(); i++ )
49 {
50 std::list<std::string> lTmp = bld.findTargets( (*i).second.c_str() );
51 for( std::list<std::string>::iterator j = lTmp.begin();
52 j != lTmp.end(); j++ )
53 {
54 add( new Command( (Command::CmdType)(*i).first, (*j).c_str() ) );
55 }
56 }
42 for( std::list<Command *>::iterator i = lCommand.begin(); 57 for( std::list<Command *>::iterator i = lCommand.begin();
43 i != lCommand.end(); i++ ) 58 i != lCommand.end(); i++ )
44 { 59 {
diff --git a/src/action.h b/src/action.h
index ea92efa..a5555a3 100644
--- a/src/action.h
+++ b/src/action.h
@@ -15,6 +15,7 @@ public:
15 virtual ~Action(); 15 virtual ~Action();
16 16
17 void add( Command *pCmd ); 17 void add( Command *pCmd );
18 void add( int nType, const char *sCmd );
18 19
19 const char *getName() 20 const char *getName()
20 { 21 {
@@ -38,6 +39,7 @@ private:
38 bool bDefault; 39 bool bDefault;
39 StaticString sName; 40 StaticString sName;
40 std::list<Command *> lCommand; 41 std::list<Command *> lCommand;
42 std::list<std::pair<int, std::string> > lRegExCommand;
41}; 43};
42 44
43#endif 45#endif
diff --git a/src/build.l b/src/build.l
index 540af46..723991b 100644
--- a/src/build.l
+++ b/src/build.l
@@ -14,7 +14,7 @@ std::string strbuf;
14%option noyywrap nounput batch debug 14%option noyywrap nounput batch debug
15 15
16%{ 16%{
17//# define YY_USER_ACTION yylloc->columns (yyleng); 17# define YY_USER_ACTION yylloc->last_column += yyleng;
18%} 18%}
19%% 19%%
20 20
@@ -34,6 +34,7 @@ std::string strbuf;
34"for" return TOK_FOR; 34"for" return TOK_FOR;
35"set" return TOK_SET; 35"set" return TOK_SET;
36"matches" return TOK_MATCHES; 36"matches" return TOK_MATCHES;
37"matching" return TOK_MATCHING;
37"all" return TOK_ALL; 38"all" return TOK_ALL;
38"one" return TOK_ONE; 39"one" return TOK_ONE;
39"perform" return TOK_PERFORM; 40"perform" return TOK_PERFORM;
@@ -41,10 +42,25 @@ std::string strbuf;
41"command" return TOK_COMMAND; 42"command" return TOK_COMMAND;
42"check" return TOK_CHECK; 43"check" return TOK_CHECK;
43"clean" return TOK_CLEAN; 44"clean" return TOK_CLEAN;
45"directories" return TOK_DIRECTORIES;
46"targets" return TOK_TARGETS;
44 47
45"..."\n /* elipsis line continuation */ 48"..."\n {
46\n+ return TOK_EOL; 49 yylloc->last_line += yyleng;
47[ \t\r]* /* whitespace */ 50 yylloc->first_line = yylloc->last_line;
51 yylloc->first_column = yylloc->last_column = 0;
52}
53\n+ {
54 yylloc->last_line += yyleng;
55 yylloc->first_line = yylloc->last_line;
56 yylloc->first_column = yylloc->last_column = 0;
57 return TOK_EOL;
58}
59
60[ \t\r]* {
61 yylloc->first_line = yylloc->last_line;
62 yylloc->first_column = yylloc->last_column+1;
63}
48 64
49"/" { 65"/" {
50 BEGIN( regexp ); 66 BEGIN( regexp );
diff --git a/src/build.y b/src/build.y
index bf565fb..d8cba53 100644
--- a/src/build.y
+++ b/src/build.y
@@ -15,10 +15,6 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
15%pure-parser 15%pure-parser
16 16
17%locations 17%locations
18%initial-action
19{
20 //@$.begin.filename = @$.end.filename = &bld.file;
21}
22 18
23%debug 19%debug
24%error-verbose 20%error-verbose
@@ -43,6 +39,7 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
43%token TOK_FOR "for" 39%token TOK_FOR "for"
44%token TOK_SET "set" 40%token TOK_SET "set"
45%token TOK_MATCHES "matches" 41%token TOK_MATCHES "matches"
42%token TOK_MATCHING "matching"
46%token TOK_ALL "all" 43%token TOK_ALL "all"
47%token TOK_ONE "one" 44%token TOK_ONE "one"
48%token TOK_PERFORM "perform" 45%token TOK_PERFORM "perform"
@@ -50,6 +47,8 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg );
50%token TOK_COMMAND "command" 47%token TOK_COMMAND "command"
51%token TOK_CHECK "check" 48%token TOK_CHECK "check"
52%token TOK_CLEAN "clean" 49%token TOK_CLEAN "clean"
50%token TOK_DIRECTORIES "directories"
51%token TOK_TARGETS "targets"
53%token TOK_EOL "end of line" 52%token TOK_EOL "end of line"
54%token ',' ':' '=' 53%token ',' ':' '='
55 54
@@ -75,7 +74,15 @@ line: TOK_DEFAULT TOK_ACTION ':'
75 bld.add( new Action( $1 ) ); 74 bld.add( new Action( $1 ) );
76 } 75 }
77 actionlst 76 actionlst
78 | TOK_CREATE createwhat TOK_FROM createfrom TOK_USING createusing 77 | TOK_FOR fortypes TOK_MATCHING REGEXP
78 {
79 bld.setFilter( $4 );
80 }
81 augments
82 {
83 bld.endList();
84 }
85 listcmds
79 | STRING TOK_REQUIRES 86 | STRING TOK_REQUIRES
80 { 87 {
81 bld.setTmp( $1 ); 88 bld.setTmp( $1 );
@@ -91,15 +98,37 @@ line: TOK_DEFAULT TOK_ACTION ':'
91 | listcmds 98 | listcmds
92 | TOK_FOR STRING 99 | TOK_FOR STRING
93 { 100 {
94 bld.setContext( $2 ); 101 bld.startList( STRING );
102 bld.addListItem( $2 );
95 } 103 }
96 listcmds 104 listcmds
97 { 105 {
98 bld.setContext(); 106
99 } 107 }
100 | rule 108 | rule
101 ; 109 ;
102 110
111fortypes: TOK_DIRECTORIES
112 {
113 bld.startList( TOK_DIRECTORIES );
114 }
115 | TOK_TARGETS
116 {
117 bld.startList( TOK_TARGETS );
118 }
119 | TOK_FILES
120 {
121 bld.startList( TOK_FILES );
122 }
123 ;
124
125augments:
126 | TOK_IN STRING
127 {
128 bld.augmentList( $2 );
129 }
130 ;
131
103reqcompletion: reqlst 132reqcompletion: reqlst
104 | TOK_FROM TOK_COMMAND STRING 133 | TOK_FROM TOK_COMMAND STRING
105 { 134 {
@@ -118,15 +147,23 @@ reqlst: STRING
118 ; 147 ;
119 148
120listcmds: TOK_SET setexpr 149listcmds: TOK_SET setexpr
150 | TOK_CREATE createwhat TOK_FROM createfrom TOK_USING createusing
151 {
152 bld.endTarget();
153 }
121 ; 154 ;
122 155
123createwhat: TOK_FILE STRING 156createwhat: TOK_FILE STRING
124 { 157 {
125 bld.add( new FileTarget( $2 ) ); 158 bld.addTarget( TOK_FILE, $2 );
126 } 159 }
127 ; 160 ;
128 161
129createfrom: TOK_FILES TOK_IN createfromdirlst 162createfrom: TOK_FILES TOK_IN
163 {
164 bld.setTargetInputType( TOK_FILES );
165 }
166 createfromdirlst
130 ; 167 ;
131 168
132createfromdirlst: createfromdir 169createfromdirlst: createfromdir
@@ -135,23 +172,13 @@ createfromdirlst: createfromdir
135 172
136createfromdir: STRING 173createfromdir: STRING
137 { 174 {
138 try 175 bld.addTargetInput( $1 );
139 {
140 ((FileTarget *)bld.lastTarget())->addInputDir( $1 );
141 }
142 catch( BuildException &e )
143 {
144 std::string s( $1 );
145 s +=": ";
146 s += e.what();
147 yyerror( &yyloc, bld, s.c_str() );
148 }
149 } 176 }
150 ; 177 ;
151 178
152createusing: TOK_RULE STRING 179createusing: TOK_RULE STRING
153 { 180 {
154 bld.lastTarget()->setRule( $2 ); 181 bld.setTargetRule( $2 );
155 } 182 }
156 ; 183 ;
157 184
@@ -163,10 +190,18 @@ action: TOK_CHECK STRING
163 { 190 {
164 bld.add( new Command( Command::cmdCheck, $2 ) ); 191 bld.add( new Command( Command::cmdCheck, $2 ) );
165 } 192 }
193 | TOK_CHECK REGEXP
194 {
195 bld.addRegexCommand( Command::cmdCheck, $2 );
196 }
166 | TOK_CLEAN STRING 197 | TOK_CLEAN STRING
167 { 198 {
168 bld.add( new Command( Command::cmdClean, $2 ) ); 199 bld.add( new Command( Command::cmdClean, $2 ) );
169 } 200 }
201 | TOK_CLEAN REGEXP
202 {
203 bld.addRegexCommand( Command::cmdClean, $2 );
204 }
170 ; 205 ;
171 206
172setexpr: STRING '=' STRING 207setexpr: STRING '=' STRING
diff --git a/src/builder.cpp b/src/builder.cpp
index a21bc99..8fd72bb 100644
--- a/src/builder.cpp
+++ b/src/builder.cpp
@@ -1,9 +1,13 @@
1#include <iostream> 1#include <iostream>
2#include <sstream>
3#include <errno.h>
4#include <dirent.h>
2 5
3#include "builder.h" 6#include "builder.h"
4#include "action.h" 7#include "action.h"
5#include "command.h" 8#include "command.h"
6#include "target.h" 9#include "target.h"
10#include "filetarget.h"
7#include "build.tab.h" 11#include "build.tab.h"
8#include "rule.h" 12#include "rule.h"
9#include "viewer.h" 13#include "viewer.h"
@@ -17,7 +21,8 @@ Builder::Builder( Viewer &rView ) :
17 pLastAddedAction( NULL ), 21 pLastAddedAction( NULL ),
18 sTmp(""), 22 sTmp(""),
19 sContext(""), 23 sContext(""),
20 rView( rView ) 24 rView( rView ),
25 bUsingList( false )
21{ 26{
22} 27}
23 28
@@ -110,6 +115,14 @@ void Builder::add( Command *pCmd )
110 } 115 }
111} 116}
112 117
118void Builder::addRegexCommand( int nType, const char *sReg )
119{
120 if( pLastAddedAction )
121 {
122 pLastAddedAction->add( nType, sReg );
123 }
124}
125
113void Builder::add( Rule *pRule ) 126void Builder::add( Rule *pRule )
114{ 127{
115 pLastAddedRule = pRule; 128 pLastAddedRule = pRule;
@@ -122,6 +135,87 @@ void Builder::add( Target *pTarg )
122 mTarget[pTarg->getName()] = pTarg; 135 mTarget[pTarg->getName()] = pTarg;
123} 136}
124 137
138void Builder::addTarget( int tokType, const char *sName )
139{
140 nTargetType = tokType;
141 sTargetName = sName;
142}
143
144void Builder::setTargetInputType( int tokType )
145{
146 nTargetInputType = tokType;
147}
148
149void Builder::addTargetInput( const char *sInput )
150{
151 lsTargetInput.push_back( sInput );
152}
153
154void Builder::setTargetRule( const char *sRule )
155{
156 sTargetRule = sRule;
157}
158
159void Builder::endTarget()
160{
161 if( bUsingList == false )
162 {
163 switch( nTargetType )
164 {
165 case TOK_FILE:
166 add( new FileTarget( sTargetName.c_str() ) );
167 switch( nTargetInputType )
168 {
169 case TOK_FILES:
170 for( std::list<std::string>::iterator
171 i = lsTargetInput.begin();
172 i != lsTargetInput.end(); i++ )
173 {
174 ((FileTarget *)lastTarget())->addInputDir(
175 (*i).c_str()
176 );
177 }
178 break;
179 }
180 lastTarget()->setRule( sTargetRule.c_str() );
181 break;
182 }
183 }
184 else
185 {
186 switch( nTargetType )
187 {
188 case TOK_FILE:
189 for( std::list<std::pair<std::string,std::map<std::string,std::string> > >::iterator j = lTok.begin(); j != lTok.end(); j++ )
190 {
191 std::string sName = varRepl( sTargetName.c_str(), "", &(*j).second );
192 add( new FileTarget( sName.c_str() ) );
193 switch( nTargetInputType )
194 {
195 case TOK_FILES:
196 for( std::list<std::string>::iterator
197 i = lsTargetInput.begin();
198 i != lsTargetInput.end(); i++ )
199 {
200 std::string sInput = varRepl(
201 (*i).c_str(), "",
202 &(*j).second
203 );
204 ((FileTarget *)lastTarget())->addInputDir(
205 sInput.c_str()
206 );
207 }
208 break;
209 }
210 lastTarget()->setRule( sTargetRule.c_str() );
211 }
212 break;
213 }
214 }
215
216 clearList();
217}
218
125void Builder::debug() 219void Builder::debug()
126{ 220{
127 printf("Actions:\n"); 221 printf("Actions:\n");
@@ -214,17 +308,31 @@ void Builder::checkVar( const char *cont, const char *sName )
214 308
215void Builder::varSet( const char *sName, const char *sValue ) 309void Builder::varSet( const char *sName, const char *sValue )
216{ 310{
217 checkVar( sContext, sName ); 311 if( bUsingList )
312 {
313 for( std::list<std::pair<std::string,std::map<std::string,std::string> > >::iterator i = lTok.begin(); i != lTok.end(); i++ )
314 {
315 checkVar( (*i).first.c_str(), sName );
218 316
219 std::string newVal = varRepl( sValue, sContext, NULL ); 317 std::string newVal = varRepl( sValue, (*i).first.c_str(), &(*i).second );
220 318
221 if( sContext[0] == '\0' ) 319 mContVar[(*i).first.c_str()][sName] = newVal;
222 { 320 }
223 mVar[sName] = newVal;
224 } 321 }
225 else 322 else
226 { 323 {
227 mContVar[sContext.getString()][sName] = newVal; 324 checkVar( sContext, sName );
325
326 std::string newVal = varRepl( sValue, sContext, NULL );
327
328 if( sContext[0] == '\0' )
329 {
330 mVar[sName] = newVal;
331 }
332 else
333 {
334 mContVar[sContext.getString()][sName] = newVal;
335 }
228 } 336 }
229} 337}
230 338
@@ -383,6 +491,17 @@ std::map<std::string, std::string> *Builder::regexVars( RegExp *re )
383 return map; 491 return map;
384} 492}
385 493
494void Builder::regexVars( RegExp *re, varmap &map )
495{
496 int jmax = re->getNumSubStrings();
497 for( int j = 0; j < jmax; j++ )
498 {
499 char buf[8];
500 sprintf( buf, "re:%d", j );
501 map[buf] = re->getSubString( j );
502 }
503}
504
386void Builder::requires( const char *sBase, const char *sReq ) 505void Builder::requires( const char *sBase, const char *sReq )
387{ 506{
388 if( bReqRegexp ) 507 if( bReqRegexp )
@@ -507,6 +626,7 @@ Rule *Builder::getRule( const char *sName )
507 if( mRule.find( sName ) != mRule.end() ) 626 if( mRule.find( sName ) != mRule.end() )
508 return mRule[sName]; 627 return mRule[sName];
509 628
629 throw BuildException("No rule named %s registered.", sName );
510 return NULL; 630 return NULL;
511} 631}
512 632
@@ -554,11 +674,128 @@ void Builder::error( const std::string &err )
554 674
555void Builder::error( YYLTYPE *locp, const std::string &err ) 675void Builder::error( YYLTYPE *locp, const std::string &err )
556{ 676{
557 fprintf( stderr, "%s:%d-%d:%d-%d: %s\n", 677 std::stringstream s;
558 file.c_str(), 678 s << file << ":" << locp->first_line << "." << locp->first_column;
559 locp->first_line, locp->last_line, 679 if( locp->first_line != locp->last_line )
560 locp->first_column, locp->last_column, 680 s << "-" << locp->last_line << "." << locp->last_column;
561 err.c_str() 681 else if( locp->first_column != locp->last_column )
562 ); 682 s << "-" << locp->last_column;
683 s << ": " << err;
684 throw BuildException( s.str().c_str() );
685}
686
687void Builder::startList( int tokType )
688{
689 bUsingList = true;
690 lTok.clear();
691 bTokFiltered = false;
692 nTokType = tokType;
693}
694
695void Builder::setFilter( const char *sRegExp )
696{
697 rTok.compile( sRegExp );
698 bTokFiltered = true;
699}
700
701void Builder::augmentList( const char *sFrom )
702{
703 switch( nTokType )
704 {
705 case TOK_DIRECTORIES:
706 {
707 DIR *dir = opendir( sFrom );
708 if( dir == NULL )
709 {
710 printf("dir: %s\n", sFrom );
711 throw BuildException( strerror( errno ) );
712 }
713
714 std::string base;
715 base += sFrom;
716 base += "/";
717
718 struct dirent *de;
719
720 while( (de = readdir( dir )) )
721 {
722 if( de->d_type != DT_DIR )
723 continue;
724 if( de->d_name[0] == '.' || de->d_name[0] == '\0' )
725 continue;
726
727 std::string s( base );
728 s += de->d_name;
729 addListItem( s.c_str() );
730 }
731
732 closedir( dir );
733 }
734 break;
735
736 default:
737 break;
738 }
739}
740
741void Builder::endList()
742{
743 switch( nTokType )
744 {
745 case TOK_TARGETS:
746 for( std::map<const char *, Target *, ltstr>::iterator i =
747 mTarget.begin(); i != mTarget.end(); i++ )
748 {
749 addListItem( (*i).first );
750 }
751 break;
752 }
753}
754
755void Builder::addListItem( const char *sItem )
756{
757 std::map<std::string,std::string> mVars;
758 mVars["match"] = sItem;
759 if( bTokFiltered )
760 {
761 if( rTok.execute( sItem ) )
762 {
763 regexVars( &rTok, mVars );
764 }
765 else
766 {
767 return;
768 }
769 }
770 lTok.push_back(
771 std::pair<std::string,std::map<std::string,std::string> >(
772 sItem, mVars
773 )
774 );
775}
776
777void Builder::clearList()
778{
779 lTok.clear();
780 lsTargetInput.clear();
781 bUsingList = false;
782}
783
784std::list<std::string> Builder::findTargets( const char *sRegex )
785{
786 RegExp r( sRegex );
787
788 std::list<std::string> lTmp;
789
790 for( std::map<const char *, Target *, ltstr>::iterator i = mTarget.begin();
791 i != mTarget.end(); i++ )
792 {
793 if( r.execute( (*i).first ) )
794 {
795 lTmp.push_back( (*i).first );
796 }
797 }
798
799 return lTmp;
563} 800}
564 801
diff --git a/src/builder.h b/src/builder.h
index 56a7b07..195296a 100644
--- a/src/builder.h
+++ b/src/builder.h
@@ -51,9 +51,23 @@ public:
51 return rView; 51 return rView;
52 } 52 }
53 53
54 void startList( int tokType );
55 void setFilter( const char *sRegExp );
56 void augmentList( const char *sFrom );
57 void addListItem( const char *sItem );
58 void clearList();
59 void endList();
60
61 void addTarget( int tokType, const char *sName );
62 void setTargetInputType( int tokType );
63 void addTargetInput( const char *sInput );
64 void setTargetRule( const char *sRule );
65 void endTarget();
66
54 void setCache( const std::string &sFile ); 67 void setCache( const std::string &sFile );
55 void add( Action *pAct ); 68 void add( Action *pAct );
56 void add( Command *pCmd ); 69 void add( Command *pCmd );
70 void addRegexCommand( int nType, const char *sReg );
57 void add( Rule *pRule ); 71 void add( Rule *pRule );
58 void add( Target *pTarg ); 72 void add( Target *pTarg );
59 void varSet( const char *sName, const char *sValue ); 73 void varSet( const char *sName, const char *sValue );
@@ -64,6 +78,7 @@ public:
64 void requires( const char *sBase, const char *sReq ); 78 void requires( const char *sBase, const char *sReq );
65 void requiresFromCommand( const char *sBase, const char *sReq ); 79 void requiresFromCommand( const char *sBase, const char *sReq );
66 void genRequiresFor( const char *sName, time_t tNewTime ); 80 void genRequiresFor( const char *sName, time_t tNewTime );
81 std::list<std::string> findTargets( const char *sRegex );
67 void requiresRegexp( bool on ) 82 void requiresRegexp( bool on )
68 { 83 {
69 bReqRegexp = on; 84 bReqRegexp = on;
@@ -119,6 +134,7 @@ public:
119 134
120 typedef std::map<std::string, std::string> varmap; 135 typedef std::map<std::string, std::string> varmap;
121 varmap *regexVars( RegExp *re ); 136 varmap *regexVars( RegExp *re );
137 void regexVars( RegExp *re, varmap &map );
122 std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra ); 138 std::string varRepl( const char *sSrc, const char *cont, varmap *mExtra );
123 139
124private: 140private:
@@ -159,6 +175,18 @@ private:
159 175
160 StaticString sCacheFile; 176 StaticString sCacheFile;
161 class Cache cRequires; 177 class Cache cRequires;
178
179 std::list<std::pair<std::string,std::map<std::string,std::string> > > lTok;
180 bool bTokFiltered;
181 int nTokType;
182 RegExp rTok;
183
184 int nTargetType;
185 int nTargetInputType;
186 std::string sTargetName;
187 std::list<std::string> lsTargetInput;
188 std::string sTargetRule;
189 bool bUsingList;
162}; 190};
163 191
164void cleanList( std::list<std::string> &lst ); 192void cleanList( std::list<std::string> &lst );
diff --git a/src/main.cpp b/src/main.cpp
index 009aac5..3ea4411 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -9,7 +9,8 @@ class Param : public ParamProc
9public: 9public:
10 Param() : 10 Param() :
11 sFile("build.conf"), 11 sFile("build.conf"),
12 sCache("build.cache") 12 sCache("build.cache"),
13 bDebug( false )
13 { 14 {
14 addHelpBanner("Build r?\n\n"); 15 addHelpBanner("Build r?\n\n");
15 addParam("file", 'f', &sFile, 16 addParam("file", 'f', &sFile,
@@ -64,7 +65,16 @@ int main( int argc, char *argv[] )
64 Builder bld( *prm.pViewer ); 65 Builder bld( *prm.pViewer );
65 66
66 bld.setCache( prm.sCache ); 67 bld.setCache( prm.sCache );
67 bld.load( prm.sFile.c_str() ); 68 try
69 {
70 bld.load( prm.sFile.c_str() );
71 }
72 catch( BuildException &e )
73 {
74 fputs( e.what(), stderr );
75 fputs( "\n", stderr );
76 return 1;
77 }
68 78
69 if( prm.bDebug ) 79 if( prm.bDebug )
70 { 80 {
diff --git a/src/regexp.cpp b/src/regexp.cpp
index ff2d09a..e5a3535 100644
--- a/src/regexp.cpp
+++ b/src/regexp.cpp
@@ -17,14 +17,21 @@ RegExp::RegExp( const char *sSrc ) :
17 17
18RegExp::~RegExp() 18RegExp::~RegExp()
19{ 19{
20 regfree( &re ); 20 if( bCompiled )
21 delete[] aSubStr; 21 {
22 regfree( &re );
23 delete[] aSubStr;
24 }
22} 25}
23 26
24void RegExp::compile( const char *sSrc ) 27void RegExp::compile( const char *sSrc )
25{ 28{
26 if( bCompiled ) 29 if( bCompiled )
27 throw BuildException("Already compiled."); 30 {
31 regfree( &re );
32 delete[] aSubStr;
33 bCompiled = false;
34 }
28 35
29 int nErr = regcomp( &re, sSrc, REG_EXTENDED|REG_NEWLINE ); 36 int nErr = regcomp( &re, sSrc, REG_EXTENDED|REG_NEWLINE );
30 if( nErr ) 37 if( nErr )
diff --git a/src/viewerplain.cpp b/src/viewerplain.cpp
index 5d95d19..52b798b 100644
--- a/src/viewerplain.cpp
+++ b/src/viewerplain.cpp
@@ -54,3 +54,8 @@ void ViewerPlain::beginExecute()
54 printf(" build: %s\n", sTarget.getString() ); 54 printf(" build: %s\n", sTarget.getString() );
55} 55}
56 56
57void ViewerPlain::executeCmd( const char *sCmd )
58{
59 //printf("--> %s\n", sCmd );
60}
61
diff --git a/src/viewerplain.h b/src/viewerplain.h
index 1ec2b64..4c88a0f 100644
--- a/src/viewerplain.h
+++ b/src/viewerplain.h
@@ -19,6 +19,7 @@ public:
19 virtual void beginExtraRequiresCheck( const char *sCommand ); 19 virtual void beginExtraRequiresCheck( const char *sCommand );
20 void printHead(); 20 void printHead();
21 virtual void beginExecute(); 21 virtual void beginExecute();
22 virtual void executeCmd( const char *sCmd );
22 23
23private: 24private:
24 class StaticString sAction; 25 class StaticString sAction;