diff options
-rw-r--r-- | main.cxx | 14 | ||||
-rw-r--r-- | parse.cxx | 19 | ||||
-rw-r--r-- | session.h | 1 | ||||
-rw-r--r-- | stap.1.in | 6 | ||||
-rwxr-xr-x | testsuite/parseko/preprocess17.stp | 3 | ||||
-rwxr-xr-x | testsuite/parseok/twenty.stp | 3 |
6 files changed, 40 insertions, 6 deletions
@@ -152,6 +152,9 @@ usage (systemtap_session& s, int exitcode) #endif // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use // only, and don't belong in the eyesight of a plain user. + << " --compatible=VERSION" << endl + << " suppress incompatible language/tapset changes beyond VERSION," << endl + << " instead of " << s.compatible << endl << " --skip-badvars" << endl << " substitute zero for bad context $variables" << endl << endl @@ -609,6 +612,7 @@ main (int argc, char * const argv []) s.skip_badvars = false; s.unprivileged = false; s.omit_werror = false; + s.compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available? bool client_options = false; string client_options_disallowed; @@ -699,6 +703,7 @@ main (int argc, char * const argv []) #define LONG_OPT_DISABLE_CACHE 11 #define LONG_OPT_POISON_CACHE 12 #define LONG_OPT_CLEAN_CACHE 13 +#define LONG_OPT_COMPATIBLE 14 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page static struct option long_options[] = { { "kelf", 0, &long_opt, LONG_OPT_KELF }, @@ -720,6 +725,7 @@ main (int argc, char * const argv []) { "disable-cache", 0, &long_opt, LONG_OPT_DISABLE_CACHE }, { "poison-cache", 0, &long_opt, LONG_OPT_POISON_CACHE }, { "clean-cache", 0, &long_opt, LONG_OPT_CLEAN_CACHE }, + { "compatible", 1, &long_opt, LONG_OPT_COMPATIBLE }, { NULL, 0, NULL, 0 } }; int grc = getopt_long (argc, argv, "hVvtp:I:e:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:W", @@ -1038,12 +1044,20 @@ main (int argc, char * const argv []) clean_cache(s); exit(0); + case LONG_OPT_COMPATIBLE: + s.compatible = optarg; + break; + default: + // NOTREACHED unless one added a getopt option but not a corresponding switch/case: + cerr << "Unhandled long argument id " << long_opt << endl; exit(1); } break; default: + // NOTREACHED unless one added a getopt option but not a corresponding switch/case: + cerr << "Unhandled argument code " << (char)grc << endl; exit(1); break; } @@ -183,6 +183,7 @@ bool eval_comparison (const OPERAND& lhs, const token* op, const OPERAND& rhs) // The basic form is %( CONDITION %? THEN-TOKENS %: ELSE-TOKENS %) // where CONDITION is: kernel_v[r] COMPARISON-OP "version-string" // or: arch COMPARISON-OP "arch-string" +// or: systemtap_v COMPARISON-OP "version-string" // or: CONFIG_foo COMPARISON-OP "config-string" // or: CONFIG_foo COMPARISON-OP number // or: CONFIG_foo COMPARISON-OP CONFIG_bar @@ -202,17 +203,21 @@ bool eval_pp_conditional (systemtap_session& s, const token* l, const token* op, const token* r) { if (l->type == tok_identifier && (l->content == "kernel_v" || - l->content == "kernel_vr")) + l->content == "kernel_vr" || + l->content == "systemtap_v")) { + if (! (r->type == tok_string)) + throw parse_error ("expected string literal", r); + string target_kernel_vr = s.kernel_release; string target_kernel_v = s.kernel_base_release; + string target; - if (! (r->type == tok_string)) - throw parse_error ("expected string literal", r); + if (l->content == "kernel_v") target = target_kernel_v; + else if (l->content == "kernel_vr") target = target_kernel_vr; + else if (l->content == "systemtap_v") target = s.compatible; + else assert (0); - string target = (l->content == "kernel_vr" ? - target_kernel_vr.c_str() : - target_kernel_v.c_str()); string query = r->content; bool rhs_wildcard = (strpbrk (query.c_str(), "*?[") != 0); @@ -2471,6 +2476,8 @@ expression* parser::parse_symbol () if (name == "@cast" || (name.size()>0 && name[0] == '$')) return parse_target_symbol (t); + // NB: PR11343: @defined() is not incompatible with earlier versions + // of stap, so no need to check session.compatible for 1.2 if (name == "@defined") return parse_defined_op (t); @@ -100,6 +100,7 @@ struct systemtap_session std::string output_file; std::string size_option; std::string cmd; + std::string compatible; // use (strverscmp(s.compatible.c_str(), "N.M") >= 0) int target_pid; int last_pass; unsigned perpass_verbose[5]; @@ -249,6 +249,12 @@ output files exceed .B \-\-skip\-badvars Ignore out of context variables and substitute with literal 0. +.TP +.BI \-\-compatible VERSION +Suppress recent script language or tapset changes which are incompatible +with given older version of systemtap. This may be useful if a much older +systemtap script fails to run. + .SH ARGUMENTS Any additional arguments on the command line are passed to the script diff --git a/testsuite/parseko/preprocess17.stp b/testsuite/parseko/preprocess17.stp new file mode 100755 index 00000000..b447776d --- /dev/null +++ b/testsuite/parseko/preprocess17.stp @@ -0,0 +1,3 @@ +#! /bin/sh + +stap --compatible=1.0 -p1 -e 'global %( systemtap_v >= "1.2" %? PASS %: "FAIL" %)' diff --git a/testsuite/parseok/twenty.stp b/testsuite/parseok/twenty.stp index d474ad5d..f03ae267 100755 --- a/testsuite/parseok/twenty.stp +++ b/testsuite/parseok/twenty.stp @@ -10,3 +10,6 @@ global %( $# != 2 && @# < "1" && @# == "0" && $# >= 3 %? %( $2 >= "12" %? $3 FAIL2 %: $2 FAIL3 %) #This line must not be evaluated %: PASS2 %) + +global +%( systemtap_v >= "1.2" %? PASS3 %: "FAIL" %) |