diff options
author | Mike Buland <eichlan@xagasoft.com> | 2006-08-06 19:42:22 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2006-08-06 19:42:22 +0000 |
commit | 71c3c523aacb0f6986d50f4a7a2e5d604728a4c4 (patch) | |
tree | 9000ae982c9cb21d31ac3efa6ccf7100064f5bbb /src/builder.cpp | |
parent | 2c0c23b75f563d0a1e68f6079a8eea73c40a877a (diff) | |
download | build-71c3c523aacb0f6986d50f4a7a2e5d604728a4c4.tar.gz build-71c3c523aacb0f6986d50f4a7a2e5d604728a4c4.tar.bz2 build-71c3c523aacb0f6986d50f4a7a2e5d604728a4c4.tar.xz build-71c3c523aacb0f6986d50f4a7a2e5d604728a4c4.zip |
A load of updates, most of these made me realize that I probably could do this
whole thing a lot better. We'll see how that works out later, once I figure out
how to do it better.
Diffstat (limited to 'src/builder.cpp')
-rw-r--r-- | src/builder.cpp | 263 |
1 files changed, 250 insertions, 13 deletions
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 | ||
118 | void Builder::addRegexCommand( int nType, const char *sReg ) | ||
119 | { | ||
120 | if( pLastAddedAction ) | ||
121 | { | ||
122 | pLastAddedAction->add( nType, sReg ); | ||
123 | } | ||
124 | } | ||
125 | |||
113 | void Builder::add( Rule *pRule ) | 126 | void 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 | ||
138 | void Builder::addTarget( int tokType, const char *sName ) | ||
139 | { | ||
140 | nTargetType = tokType; | ||
141 | sTargetName = sName; | ||
142 | } | ||
143 | |||
144 | void Builder::setTargetInputType( int tokType ) | ||
145 | { | ||
146 | nTargetInputType = tokType; | ||
147 | } | ||
148 | |||
149 | void Builder::addTargetInput( const char *sInput ) | ||
150 | { | ||
151 | lsTargetInput.push_back( sInput ); | ||
152 | } | ||
153 | |||
154 | void Builder::setTargetRule( const char *sRule ) | ||
155 | { | ||
156 | sTargetRule = sRule; | ||
157 | } | ||
158 | |||
159 | void 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 | |||
125 | void Builder::debug() | 219 | void 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 | ||
215 | void Builder::varSet( const char *sName, const char *sValue ) | 309 | void 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 | ||
494 | void 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 | |||
386 | void Builder::requires( const char *sBase, const char *sReq ) | 505 | void 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 | ||
555 | void Builder::error( YYLTYPE *locp, const std::string &err ) | 675 | void 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 | |||
687 | void Builder::startList( int tokType ) | ||
688 | { | ||
689 | bUsingList = true; | ||
690 | lTok.clear(); | ||
691 | bTokFiltered = false; | ||
692 | nTokType = tokType; | ||
693 | } | ||
694 | |||
695 | void Builder::setFilter( const char *sRegExp ) | ||
696 | { | ||
697 | rTok.compile( sRegExp ); | ||
698 | bTokFiltered = true; | ||
699 | } | ||
700 | |||
701 | void 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 | |||
741 | void 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 | |||
755 | void 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 | |||
777 | void Builder::clearList() | ||
778 | { | ||
779 | lTok.clear(); | ||
780 | lsTargetInput.clear(); | ||
781 | bUsingList = false; | ||
782 | } | ||
783 | |||
784 | std::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 | ||