]>
sourceware.org Git - systemtap.git/blob - stapregex.cxx
2 // Copyright (C) 2012-2013 Red Hat Inc.
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
11 // This file incorporates code from the re2c project; please see
12 // the file README.stapregex for details.
15 #include "translator-output.h"
18 #include "staptree.h" // needed to use semantic_error
27 #include "stapregex-parse.h"
28 #include "stapregex-tree.h"
29 #include "stapregex-dfa.h"
30 #include "stapregex.h"
32 using namespace stapregex
;
34 // ------------------------------------------------------------------------
37 regex_to_stapdfa (systemtap_session
*s
, const string
& input
, const token
*tok
)
39 // Tags are disabled when not used, for the extra bit of efficiency.
40 bool do_tag
= s
->need_tagged_dfa
;
42 if (s
->dfas
.find(input
) != s
->dfas
.end())
43 return s
->dfas
[input
];
45 stapdfa
*dfa
= new stapdfa ("__stp_dfa" + lex_cast(s
->dfa_counter
++), input
, tok
, true, do_tag
);
47 // Update required size of subexpression-tracking data structure:
48 s
->dfa_maxstate
= max(s
->dfa_maxstate
, dfa
->num_states());
49 s
->dfa_maxtag
= max(s
->dfa_maxtag
, dfa
->num_tags());
55 // ------------------------------------------------------------------------
57 stapdfa::stapdfa (const string
& func_name
, const string
& re
,
58 const token
*tok
, bool do_unescape
, bool do_tag
)
59 : func_name(func_name
), orig_input(re
), tok(tok
), do_tag(do_tag
)
63 regex_parser
p(re
, do_unescape
);
64 ast
= p
.parse (do_tag
);
65 content
= stapregex_compile (ast
, "goto match_success;", "goto match_fail;");
67 catch (const regex_error
&e
)
70 throw SEMANTIC_ERROR(_F("regex compilation error (at position %d): %s",
71 e
.pos
, e
.what()), tok
);
73 throw SEMANTIC_ERROR(_F("regex compilation error: %s", e
.what()), tok
);
84 stapdfa::num_states () const
86 return content
->nstates
;
90 stapdfa::num_tags () const
92 return content
->ntags
;
96 stapdfa::emit_declaration (translator_output
*o
) const
98 o
->newline() << "// DFA for \"" << orig_input
<< "\"";
99 o
->newline() << "int " << func_name
<< " (struct context * __restrict__ c, const char *str) {";
102 // Emit a SystemTap function body (as if an embedded-C snippet) that
103 // invokes the DFA on the argument named 'str', saves a boolean
104 // value (0 or 1) in the return value, and updates the probe
105 // context's match object with subexpression contents as
108 o
->newline() << "const char *cur = str;";
109 o
->newline() << "const char *mar;";
112 o
->newline() << "#define YYTAG(t,s,n) {c->last_match.tag_states[(t)][(s)] = (n);}";
113 o
->newline() << "#define YYCTYPE char";
114 o
->newline() << "#define YYCURSOR cur";
115 o
->newline() << "#define YYLIMIT cur";
116 o
->newline() << "#define YYMARKER mar";
117 // XXX: YYFILL is disabled as it doesn't play well with ^
124 catch (const regex_error
&e
)
127 throw SEMANTIC_ERROR(_F("regex compilation error (at position %d): %s",
128 e
.pos
, e
.what()), tok
);
130 throw SEMANTIC_ERROR(_F("regex compilation error: %s", e
.what()), tok
);
133 o
->newline() << "#undef YYCTYPE";
134 o
->newline() << "#undef YYCURSOR";
135 o
->newline() << "#undef YYLIMIT";
136 o
->newline() << "#undef YYMARKER";
138 o
->newline() << "match_success:";
141 o
->newline() << "strlcpy (c->last_match.matched_str, str, MAXSTRINGLEN);";
142 o
->newline() << "c->last_match.result = 1";
143 content
->emit_tagsave(o
, "c->last_match.tag_states", "c->last_match.tag_vals", "c->last_match.num_final_tags");
145 o
->newline() << "return 1;";
147 o
->newline() << "match_fail:";
150 o
->newline() << "strlcpy (c->last_match.matched_str, str, MAXSTRINGLEN);";
151 o
->newline() << "c->last_match.result = 0;";
153 o
->newline() << "return 0;";
155 o
->newline(-1) << "}";
159 stapdfa::emit_matchop_start (translator_output
*o
) const
161 o
->line() << "(" << func_name
<< "(c, ("; // XXX: assumes context is available
165 stapdfa::emit_matchop_end (translator_output
*o
) const
171 stapdfa::print (std::ostream
& o
) const
173 translator_output
to(o
); print(&to
);
177 stapdfa::print (translator_output
*o
) const
179 o
->line() << "STAPDFA (" << func_name
<< ", \"" << orig_input
<< "\") {";
181 o
->newline(-1) << "}";
185 operator << (std::ostream
&o
, const stapdfa
& d
)
191 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.044887 seconds and 5 git commands to generate.