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 | ||
