diff options
Diffstat (limited to '')
| -rw-r--r-- | src/builder.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/builder.cpp b/src/builder.cpp index e5017e2..8e29c81 100644 --- a/src/builder.cpp +++ b/src/builder.cpp | |||
| @@ -32,6 +32,28 @@ void Builder::load( const char *sFN ) | |||
| 32 | scanEnd(); | 32 | scanEnd(); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void Builder::build( const char *sAct ) | ||
| 36 | { | ||
| 37 | Action *pAct; | ||
| 38 | if( sAct == NULL ) | ||
| 39 | pAct = pDefaultAction; | ||
| 40 | else | ||
| 41 | { | ||
| 42 | if( mAction.find( sAct ) == mAction.end() ) | ||
| 43 | throw BuildException("No action matches '%s'.", sAct ); | ||
| 44 | pAct = mAction[sAct]; | ||
| 45 | } | ||
| 46 | |||
| 47 | printf("--- %s ---\n", pAct->getName() ); | ||
| 48 | |||
| 49 | pAct->execute( *this ); | ||
| 50 | } | ||
| 51 | |||
| 52 | void Builder::execute( Action *pAct ) | ||
| 53 | { | ||
| 54 | pAct->execute( *this ); | ||
| 55 | } | ||
| 56 | |||
| 35 | void Builder::add( Action *pAct ) | 57 | void Builder::add( Action *pAct ) |
| 36 | { | 58 | { |
| 37 | if( pAct->isDefault() ) | 59 | if( pAct->isDefault() ) |
| @@ -185,8 +207,125 @@ void Builder::varAddSet( const char *sName, const char *sValue ) | |||
| 185 | } | 207 | } |
| 186 | } | 208 | } |
| 187 | 209 | ||
| 210 | void Builder::processRequires( std::list<std::string> &lInput ) | ||
| 211 | { | ||
| 212 | for( regreqlist::iterator i = lRequiresRegexp.begin(); | ||
| 213 | i != lRequiresRegexp.end(); i++ ) | ||
| 214 | { | ||
| 215 | RegExp *re = (*i).first; | ||
| 216 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
| 217 | j != lInput.end(); j++ ) | ||
| 218 | { | ||
| 219 | if( re->execute( (*j).c_str() ) ) | ||
| 220 | { | ||
| 221 | varmap *revars = regexVars( re ); | ||
| 222 | requiresNormal( | ||
| 223 | (*j).c_str(), | ||
| 224 | varRepl( | ||
| 225 | (*i).second.c_str(), | ||
| 226 | "", | ||
| 227 | revars | ||
| 228 | ).c_str() | ||
| 229 | ); | ||
| 230 | delete revars; | ||
| 231 | } | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | for( regreqlist::iterator i = lRequiresRegexpCommand.begin(); | ||
| 236 | i != lRequiresRegexpCommand.end(); i++ ) | ||
| 237 | { | ||
| 238 | RegExp *re = (*i).first; | ||
| 239 | for( std::list<std::string>::iterator j = lInput.begin(); | ||
| 240 | j != lInput.end(); j++ ) | ||
| 241 | { | ||
| 242 | if( re->execute( (*j).c_str() ) ) | ||
| 243 | { | ||
| 244 | varmap *revars = regexVars( re ); | ||
| 245 | FILE *fcmd = popen( | ||
| 246 | varRepl( (*i).second.c_str(), "", revars ).c_str(), | ||
| 247 | "r" ); | ||
| 248 | std::string rhs; | ||
| 249 | bool bHeader = true; | ||
| 250 | for(;;) | ||
| 251 | { | ||
| 252 | if( feof( fcmd ) ) | ||
| 253 | break; | ||
| 254 | int cc = fgetc( fcmd ); | ||
| 255 | if( cc == EOF ) | ||
| 256 | break; | ||
| 257 | unsigned char c = cc; | ||
| 258 | if( bHeader ) | ||
| 259 | { | ||
| 260 | if( c == ':' ) | ||
| 261 | bHeader = false; | ||
| 262 | } | ||
| 263 | else | ||
| 264 | { | ||
| 265 | if( c == ' ' || c == '\t' ) | ||
| 266 | { | ||
| 267 | if( rhs != "" ) | ||
| 268 | { | ||
| 269 | requiresNormal( | ||
| 270 | (*j).c_str(), | ||
| 271 | rhs.c_str() | ||
| 272 | ); | ||
| 273 | rhs = ""; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | else | ||
| 277 | { | ||
| 278 | if( c == '\\' ) | ||
| 279 | c = fgetc( fcmd ); | ||
| 280 | if( c != '\n' ) | ||
| 281 | rhs += c; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | } | ||
| 285 | if( rhs != "" ) | ||
| 286 | { | ||
| 287 | requiresNormal( | ||
| 288 | (*j).c_str(), | ||
| 289 | rhs.c_str() | ||
| 290 | ); | ||
| 291 | rhs = ""; | ||
| 292 | } | ||
| 293 | fclose( fcmd ); | ||
| 294 | delete revars; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | std::map<std::string, std::string> *Builder::regexVars( RegExp *re ) | ||
| 301 | { | ||
| 302 | varmap *map = new varmap; | ||
| 303 | |||
| 304 | int jmax = re->getNumSubStrings(); | ||
| 305 | for( int j = 0; j < jmax; j++ ) | ||
| 306 | { | ||
| 307 | char buf[8]; | ||
| 308 | sprintf( buf, "re:%d", j ); | ||
| 309 | (*map)[buf] = re->getSubString( j ); | ||
| 310 | } | ||
| 311 | |||
| 312 | return map; | ||
| 313 | } | ||
| 314 | |||
| 188 | void Builder::requires( const char *sBase, const char *sReq ) | 315 | void Builder::requires( const char *sBase, const char *sReq ) |
| 189 | { | 316 | { |
| 317 | if( bReqRegexp ) | ||
| 318 | { | ||
| 319 | requiresRegexp( sBase, sReq ); | ||
| 320 | } | ||
| 321 | else | ||
| 322 | { | ||
| 323 | requiresNormal( sBase, sReq ); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | void Builder::requiresNormal( const char *sBase, const char *sReq ) | ||
| 328 | { | ||
| 190 | std::list<std::string> *pList = NULL; | 329 | std::list<std::string> *pList = NULL; |
| 191 | if( mRequires.find(sBase) == mRequires.end() ) | 330 | if( mRequires.find(sBase) == mRequires.end() ) |
| 192 | { | 331 | { |
| @@ -201,6 +340,26 @@ void Builder::requires( const char *sBase, const char *sReq ) | |||
| 201 | pList->push_back( sReq ); | 340 | pList->push_back( sReq ); |
| 202 | } | 341 | } |
| 203 | 342 | ||
| 343 | void Builder::requiresRegexp( const char *sBase, const char *sReq ) | ||
| 344 | { | ||
| 345 | lRequiresRegexp.push_back( | ||
| 346 | std::pair<RegExp *, std::string>( | ||
| 347 | new RegExp( sBase ), | ||
| 348 | sReq | ||
| 349 | ) | ||
| 350 | ); | ||
| 351 | } | ||
| 352 | |||
| 353 | void Builder::requiresFromCommand( const char *sBase, const char *sCmd ) | ||
| 354 | { | ||
| 355 | lRequiresRegexpCommand.push_back( | ||
| 356 | std::pair<RegExp *, std::string>( | ||
| 357 | new RegExp( sBase ), | ||
| 358 | sCmd | ||
| 359 | ) | ||
| 360 | ); | ||
| 361 | } | ||
| 362 | |||
| 204 | void Builder::setContext( const char *sCont ) | 363 | void Builder::setContext( const char *sCont ) |
| 205 | { | 364 | { |
| 206 | sContext = sCont; | 365 | sContext = sCont; |
| @@ -211,3 +370,79 @@ void Builder::setContext() | |||
| 211 | setContext(""); | 370 | setContext(""); |
| 212 | } | 371 | } |
| 213 | 372 | ||
| 373 | bool Builder::hasVar( varmap *pMap, std::string &var ) | ||
| 374 | { | ||
| 375 | if( pMap == NULL ) | ||
| 376 | return false; | ||
| 377 | if( pMap->find( var ) == pMap->end() ) | ||
| 378 | return false; | ||
| 379 | return true; | ||
| 380 | } | ||
| 381 | |||
| 382 | std::string Builder::varRepl( const char *sSrc, const char *cont, varmap *mExtra ) | ||
| 383 | { | ||
| 384 | varmap *mCont = NULL; | ||
| 385 | if( cont[0] != '\0' ) | ||
| 386 | { | ||
| 387 | if( mContVar.find( cont ) != mContVar.end() ) | ||
| 388 | mCont = &mContVar[cont]; | ||
| 389 | } | ||
| 390 | |||
| 391 | std::string out; | ||
| 392 | std::string var; | ||
| 393 | bool bVar = false; | ||
| 394 | |||
| 395 | for( const char *s = sSrc; *s; s++ ) | ||
| 396 | { | ||
| 397 | if( *s == '{' ) | ||
| 398 | { | ||
| 399 | bVar = true; | ||
| 400 | continue; | ||
| 401 | } | ||
| 402 | else if( *s == '}' && bVar ) | ||
| 403 | { | ||
| 404 | if( hasVar( &mVar, var ) ) | ||
| 405 | { | ||
| 406 | out += mVar[var]; | ||
| 407 | } | ||
| 408 | else if( hasVar( mCont, var ) ) | ||
| 409 | { | ||
| 410 | out += (*mCont)[var]; | ||
| 411 | } | ||
| 412 | else if( hasVar( mExtra, var ) ) | ||
| 413 | { | ||
| 414 | out += (*mExtra)[var]; | ||
| 415 | } | ||
| 416 | var = ""; | ||
| 417 | bVar = false; | ||
| 418 | continue; | ||
| 419 | } | ||
| 420 | |||
| 421 | if( bVar == true ) | ||
| 422 | { | ||
| 423 | var += *s; | ||
| 424 | } | ||
| 425 | else | ||
| 426 | { | ||
| 427 | out += *s; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | return out; | ||
| 432 | } | ||
| 433 | |||
| 434 | Rule *Builder::getRule( const char *sName ) | ||
| 435 | { | ||
| 436 | if( mRule.find( sName ) != mRule.end() ) | ||
| 437 | return mRule[sName]; | ||
| 438 | |||
| 439 | return NULL; | ||
| 440 | } | ||
| 441 | |||
| 442 | std::list<Rule *> Builder::findRuleChain( Rule *pRule ) | ||
| 443 | { | ||
| 444 | std::list<Rule *> ret; | ||
| 445 | |||
| 446 | return ret; | ||
| 447 | } | ||
| 448 | |||
