muSED.cxx
Go to the documentation of this file.00001 #include <cxxtls/muSED.h>
00002
00003 namespace cxxtls
00004 {
00005 namespace muSED
00006 {
00007
00009 void expandEscapes(std::string &input)
00010 {
00011
00012
00013 std::string tmp;
00014
00015 char const *scan = input.data();
00016 char const *end = scan + input.size();
00017
00018 while(scan != end)
00019 {
00020 char c= *scan;
00021
00022 if(c == '\\')
00023 {
00024 ++scan;
00025
00026 if(scan == end)
00027 {
00028 tmp += '\\';
00029
00030 break;
00031 }
00032 else
00033 switch(c = *scan++)
00034 {
00035 case 'n': tmp += '\n'; break;
00036 case 'r': tmp += '\r'; break;
00037 case 't': tmp += '\t'; break;
00038 case 'a': tmp += '\a'; break;
00039 case 'b': tmp += '\b'; break;
00040
00041 case 'e': tmp += char(0x1b); break;
00042
00043 default:
00044 tmp += '\\';
00045 tmp += c;
00046
00047 }
00048
00049
00050 }
00051 else
00052 {
00053 tmp += c;
00054 ++scan;
00055 }
00056
00057
00058
00059 }
00060
00061
00062 input.swap(tmp);
00063
00064 }
00065
00067 bool Filter::passes(size_t lineNo, bool isLast, std::string const &line)
00068 {
00069 switch(type_)
00070 {
00071 case regex:
00072
00073 if(!regex_(line))
00074 return false;
00075
00076
00077
00078 break;
00079
00080 case lineNumber:
00081
00082 return line_ == lineNo;
00083
00084 case lastLine:
00085 return isLast;
00086
00087 default:
00088 break;
00089
00090 }
00091
00092 return true;
00093
00094 }
00096 std::string Filter::debugString() const
00097 {
00098 switch(type_)
00099 {
00100 case regex: return std::string("regex(") + std::string(regex_) + ")";
00101 case lastLine: return std::string("lastLine()");
00102
00103 case lineNumber:
00104 {
00105 char buffer[256];
00106
00107 snprintf(buffer, sizeof(buffer), "line(%d)", int(line_));
00108
00109 return buffer;
00110 }
00111
00112 default:
00113 break;
00114 }
00115
00116 return "<none>";
00117 }
00119 LineRangeActivationState Statement::activationState()
00120 {
00121 ActivationMap *am= 0;
00122
00123 if(parentStatement_)
00124 am = &parentStatement_->childStatementActivationMap_;
00125 else
00126 am = & childStatementActivationMap_;
00127
00128 if(am->find(this) == am->end())
00129 {
00130 return neverExecuted;
00131 }
00132
00133 return (*am)[this];
00134
00135
00136 }
00138 void Statement::setActivationState(LineRangeActivationState newState)
00139 {
00140 ActivationMap *am = 0;
00141
00142 if(parentStatement_)
00143 am = &parentStatement_->childStatementActivationMap_;
00144 else
00145 am = &childStatementActivationMap_;
00146
00147 ActivationMap::iterator loc = am->find(this);
00148
00149 if(loc == am->end())
00150 {
00151 if(newState == inRange)
00152 {
00153
00154
00155 childStatementActivationMap_.clear();
00156
00157 }
00158
00159 (*am)[this] = newState;
00160 }
00161 else
00162 {
00163 if(newState == inRange && loc->second != inRange)
00164 {
00165 childStatementActivationMap_.clear();
00166 }
00167
00168 loc->second = newState;
00169 }
00170
00171 }
00173 void ScriptRuntimeContext::print(bool firstLineOnly)
00174 {
00175 char const *start = patternBuffer()->data();
00176 char const *end = start + patternBuffer()->size();
00177
00178 for(;;)
00179 {
00180 char const *scan;
00181
00182
00183
00184
00185 for(scan = start; scan != end; ++scan)
00186 if(*scan == '\n')
00187 break;
00188
00189 if(scan == end)
00190 {
00191
00192
00193
00194 output_->push_back( std::string(start, scan) );
00195 break;
00196 }
00197 else
00198 {
00199
00200
00201
00202 output_->push_back( std::string(start, scan) );
00203 start = scan+1;
00204
00205 if(firstLineOnly)
00206 {
00207 break;
00208 }
00209
00210 }
00211
00212 }
00213
00214
00215 }
00217
00218 bool SubstStatement::execute(ScriptRuntimeContext *context)
00219 {
00220
00221 if(!active(context, this))
00222 return false;
00223
00224
00225 std::string *pattern = context->patternBuffer();
00226
00227 std::string rv;
00228
00229 if(target_(*pattern))
00230 {
00231 std::string rv;
00232
00233 int replaced;
00234
00235 if(count_)
00236 {
00237 replaced = target_.replace(rv, *pattern, replacement_, count_);
00238 }
00239 else
00240 {
00241
00242
00243 replaced = target_.replace(rv, *pattern, replacement_);
00244 }
00245
00246
00247 if(replaced)
00248 {
00249
00250
00251 *pattern = rv;
00252 }
00253
00254 }
00255
00256
00257 return false;
00258 }
00260
00261 bool TranslateStatement::execute(ScriptRuntimeContext *context)
00262 {
00263
00264 if(!active(context, this))
00265 return false;
00266
00267 std::string *pattern = context->patternBuffer();
00268
00269 *pattern = translator_.translate(*pattern);
00270
00271 return false;
00272 }
00274
00275 bool BlockStatement::execute(ScriptRuntimeContext *context)
00276 {
00277 if(!active(context, this))
00278 return false;
00279
00280 int maxCount = context->maxWhileIterations();
00281
00282 if(whileCondition_.get())
00283 {
00284 SimpleRegex const &condition(*whileCondition_);
00285
00286 for(;;)
00287 {
00288 --maxCount;
00289
00290 if(maxCount == 0)
00291 return true;
00292
00293 if(!condition(*context->patternBuffer()) )
00294 break;
00295
00296 CXXTLS_FOREACH(Statement *s, childStatements_)
00297 {
00298 if(s->execute(context))
00299 return true;
00300 }
00301 }
00302 }
00303 else
00304 {
00305 CXXTLS_FOREACH(Statement *s, childStatements_)
00306 {
00307 if(s->execute(context))
00308 return true;
00309 }
00310 }
00311
00312 return false;
00313 }
00315
00316 bool FilterableStatement::active(ScriptRuntimeContext *context, Statement *statement)
00317 {
00318
00319 if(filters_)
00320 {
00321
00322
00323
00324
00325 if(filters_ == 1)
00326 {
00327
00328
00329
00330
00331
00332 bool f1Passed =
00333 filter1_.passes(context->lineNumber_,
00334 context->isLast_,
00335 *context->patternBuffer()
00336 );
00337
00338 if(inverted_)
00339 return !f1Passed;
00340 else
00341 return f1Passed;
00342 }
00343 else
00344 {
00345
00346
00347 LineRangeActivationState currentState = activationState();
00348
00349 switch(currentState)
00350 {
00351 case neverExecuted:
00352 {
00353 if(!inverted_)
00354 {
00355
00356
00357
00358 bool passed;
00359
00360 passed =
00361 filter1_.passes(context->lineNumber_,
00362 context->isLast_,
00363 *context->patternBuffer()
00364 );
00365
00366 if(passed)
00367 {
00368
00369
00370 passed =
00371 filter2_.passes(context->lineNumber_,
00372 context->isLast_,
00373 *context->patternBuffer()
00374 );
00375
00376 if(!passed)
00377 {
00378
00379
00380 setActivationState(inRange);
00381 return true;
00382
00383 }
00384 else
00385 {
00386 return true;
00387
00388 }
00389
00390 }
00391 else
00392 {
00393 return false;
00394
00395 }
00396
00397 }
00398 else
00399 {
00400
00401
00402 bool passed;
00403
00404 passed =
00405 filter1_.passes(context->lineNumber_,
00406 context->isLast_,
00407 *context->patternBuffer()
00408 );
00409
00410 if(passed)
00411 {
00412
00413
00414
00415
00416
00417
00418 passed =
00419 filter2_.passes(context->lineNumber_,
00420 context->isLast_,
00421 *context->patternBuffer()
00422 );
00423
00424 if(passed)
00425 {
00426
00427
00428
00429
00430 setActivationState(inRange);
00431 return true;
00432 }
00433 else
00434 {
00435 setActivationState(neverExecuted);
00436 return false;
00437 }
00438 }
00439 else
00440 {
00441
00442
00443
00444 setActivationState(inRange);
00445 return true;
00446 }
00447 }
00448 }
00449
00450
00451 case inRange:
00452 {
00453 if(!inverted_)
00454 {
00455
00456
00457
00458 bool passed;
00459
00460 passed =
00461 filter2_.passes(context->lineNumber_,
00462 context->isLast_,
00463 *context->patternBuffer()
00464 );
00465
00466 if(!passed)
00467 {
00468 return true;
00469 }
00470 else
00471 {
00472
00473
00474
00475 setActivationState(neverExecuted);
00476 return true;
00477 }
00478
00479 }
00480 else
00481 {
00482
00483
00484 bool passed;
00485
00486 passed =
00487 filter1_.passes(context->lineNumber_,
00488 context->isLast_,
00489 *context->patternBuffer()
00490 );
00491
00492 if(passed)
00493 {
00494
00495
00496
00497 setActivationState(neverExecuted);
00498 return true;
00499
00500
00501 }
00502 else
00503 return true;
00504
00505 }
00506 }
00507
00508
00509
00510 default:
00511
00512 debugPrint(this);
00513
00514 throw int(9);
00515
00516 return false;
00517 }
00518
00519 }
00520
00521
00522 throw float(10);
00523 return false;
00524 }
00525
00526 if(inverted_)
00527 return false;
00528
00529 return true;
00530 }
00531
00533 bool OuterStatement::execute(ScriptRuntimeContext *context)
00534 {
00535 CXXTLS_FOREACH(Statement *s, childStatements_)
00536 {
00537 if(s->execute(context))
00538 return true;
00539 }
00540
00541 return false;
00542 }
00543
00545 std::string FilterableStatement::debugStringPrefix() const
00546 {
00547 if(filters_ == 0)
00548 {
00549 return debugPrefix();
00550 }
00551
00552 std::string rv = debugPrefix() + filter1_.debugString();
00553
00554 if(filters_ > 1)
00555 {
00556 rv += ",";
00557 rv += filter2_.debugString();
00558 }
00559
00560 if(inverted_)
00561 {
00562 rv += "!";
00563 }
00564
00565 return rv;
00566
00567 }
00569
00570 std::string BlockStatement::debugString() const
00571 {
00572 std::string rv = debugStringPrefix();
00573
00574 rv += "{";
00575
00576 CXXTLS_FOREACH(Statement *cur, childStatements_)
00577 {
00578 rv += cur->debugString();
00579 rv += ";";
00580 }
00581
00582 rv += "}";
00583
00584 return rv;
00585 }
00586
00588
00589 std::string SubstStatement::debugString() const
00590 {
00591 std::string rv = debugStringPrefix();
00592
00593 rv += "s/";
00594 rv += target_;
00595 rv += "/";
00596 rv += replacement_;
00597
00598 char buffer[40];
00599
00600 snprintf(buffer, sizeof(buffer), "%d", count_);
00601
00602 rv += buffer;
00603
00604 return rv;
00605 }
00606
00608
00609 std::string TranslateStatement::debugString() const
00610 {
00611 std::string rv = debugStringPrefix();
00612
00613 rv += "y/";
00614 rv += target_;
00615 rv += "/";
00616 rv += replacement_;
00617
00618 return rv;
00619 }
00621
00622 std::string PrintStatement::debugString() const
00623 {
00624 std::string rv = debugStringPrefix();
00625
00626 rv += "p";
00627
00628 return rv;
00629 }
00630
00632 std::string SwapStatement::debugString() const
00633 {
00634 std::string rv = debugStringPrefix();
00635
00636 rv += "x";
00637
00638 return rv;
00639 }
00640
00641
00643 std::string DeleteStatement::debugString() const
00644 {
00645 std::string rv = debugStringPrefix();
00646
00647 rv += "d";
00648
00649 return rv;
00650 }
00652 std::string QuitStatement::debugString() const
00653 {
00654 std::string rv = debugStringPrefix();
00655
00656 if(printCurrent_)
00657 rv += "q";
00658 else
00659 rv += "Q";
00660
00661 return rv;
00662 }
00663
00665 std::string HoldStatement::debugString() const
00666 {
00667 std::string rv = debugStringPrefix();
00668
00669 if(append_)
00670 rv += "H";
00671 else
00672 rv += "h";
00673
00674 return rv;
00675 }
00676
00678 std::string GetStatement::debugString() const
00679 {
00680 std::string rv = debugStringPrefix();
00681
00682 if(append_)
00683 rv += "G";
00684 else
00685 rv += "g";
00686
00687 return rv;
00688 }
00689
00691
00692 bool PrintStatement::execute(ScriptRuntimeContext *context)
00693 {
00694 if(!active(context, this))
00695 return false;
00696
00697 context->print(firstLineOnly_);
00698
00699
00700 return false;
00701 }
00702
00704
00705 bool HoldStatement::execute(ScriptRuntimeContext *context)
00706 {
00707 if(!active(context, this))
00708 return false;
00709
00710
00711 if(append_)
00712 context->Hold();
00713 else
00714 context->hold();
00715
00716
00717 return false;
00718 }
00719
00721
00722 bool SwapStatement::execute(ScriptRuntimeContext *context)
00723 {
00724 if(!active(context, this))
00725 return false;
00726
00727 context->bufferSwap();
00728
00729 return false;
00730 }
00731
00732
00734
00735 bool GetStatement::execute(ScriptRuntimeContext *context)
00736 {
00737 if(!active(context, this))
00738 return false;
00739
00740 if(append_)
00741 context->Get();
00742 else
00743 context->get();
00744
00745
00746 return false;
00747 }
00748
00750 bool DeleteStatement::execute(ScriptRuntimeContext *context)
00751 {
00752 if(!active(context, this))
00753 return false;
00754
00755 return true;
00756 }
00757
00758
00760 bool QuitStatement::execute(ScriptRuntimeContext *context)
00761 {
00762 if(!active(context, this))
00763 return false;
00764
00765 if(printCurrent_)
00766 context->print(false);
00767
00768 context->stop();
00769
00770 return true;
00771 }
00772
00773
00776
00777 };
00778 };
00779