*/
#pragma once
-#include <unordered_map>
#include <string>
+#include <unordered_map>
namespace USDT {
-struct Argument {
- int arg_size;
- int constant;
- int deref_offset;
- std::string deref_ident;
- std::string register_name;
+class ArgumentParser;
+
+class Argument {
+ private:
+ int arg_size_;
+ int constant_;
+ int deref_offset_;
+ std::string deref_ident_;
+ std::string register_name_;
+
+ public:
+ Argument();
+ ~Argument();
- Argument() : arg_size(0), constant(0), deref_offset(0) {}
+ const std::string &deref_ident() const { return deref_ident_; }
+ const std::string ®ister_name() const { return register_name_; }
+ int arg_size() const { return arg_size_; }
+ int constant() const { return constant_; }
+ int deref_offset() const { return deref_offset_; }
+ friend class ArgumentParser;
};
class ArgumentParser {
ssize_t cur_pos_;
protected:
- virtual bool validate_register(const std::string ®, int ®_size) = 0;
+ virtual bool validate_register(const std::string ®, int *reg_size) = 0;
- ssize_t parse_number(ssize_t pos, int &number);
- ssize_t parse_identifier(ssize_t pos, std::string &ident);
- ssize_t parse_register(ssize_t pos, Argument &dest);
- ssize_t parse_expr(ssize_t pos, Argument &dest);
- ssize_t parse_1(ssize_t pos, Argument &dest);
+ ssize_t parse_number(ssize_t pos, int *number);
+ ssize_t parse_identifier(ssize_t pos, std::string *ident);
+ ssize_t parse_register(ssize_t pos, Argument *dest);
+ ssize_t parse_expr(ssize_t pos, Argument *dest);
+ ssize_t parse_1(ssize_t pos, Argument *dest);
void print_error(ssize_t pos);
public:
- bool parse(Argument &dest);
+ bool parse(Argument *dest);
bool done() { return arg_[cur_pos_] == '\0'; }
ArgumentParser(const char *arg) : arg_(arg), cur_pos_(0) {}
class ArgumentParser_x64 : public ArgumentParser {
static const std::unordered_map<std::string, int> registers_;
- bool validate_register(const std::string ®, int ®_size);
+ bool validate_register(const std::string ®, int *reg_size);
public:
ArgumentParser_x64(const char *arg) : ArgumentParser(arg) {}
* limitations under the License.
*/
#include <unordered_map>
-#include <stdio.h>
-
#include "usdt.h"
namespace USDT {
-ssize_t ArgumentParser::parse_number(ssize_t pos, int &number) {
+Argument::Argument() : arg_size_(0), constant_(0), deref_offset_(0) {}
+
+Argument::~Argument() {}
+
+ssize_t ArgumentParser::parse_number(ssize_t pos, int *number) {
char *endp;
- number = strtol(arg_ + pos, &endp, 0);
+ *number = strtol(arg_ + pos, &endp, 0);
return endp - arg_;
}
-ssize_t ArgumentParser::parse_identifier(ssize_t pos, std::string &ident) {
+ssize_t ArgumentParser::parse_identifier(ssize_t pos, std::string *ident) {
if (isalpha(arg_[pos]) || arg_[pos] == '_') {
ssize_t start = pos++;
while (isalnum(arg_[pos]) || arg_[pos] == '_') pos++;
- ident.assign(arg_ + start, pos - start);
+ ident->assign(arg_ + start, pos - start);
}
return pos;
}
-ssize_t ArgumentParser::parse_register(ssize_t pos, Argument &dest) {
+ssize_t ArgumentParser::parse_register(ssize_t pos, Argument *dest) {
ssize_t start = pos++;
if (arg_[start] != '%')
return -start;
while (isalnum(arg_[pos])) pos++;
- dest.register_name.assign(arg_ + start, pos - start);
- if (!validate_register(dest.register_name, dest.arg_size))
+ dest->register_name_.assign(arg_ + start, pos - start);
+ if (!validate_register(dest->register_name(), &dest->arg_size_))
return -start;
return pos;
}
-ssize_t ArgumentParser::parse_expr(ssize_t pos, Argument &dest) {
+ssize_t ArgumentParser::parse_expr(ssize_t pos, Argument *dest) {
if (arg_[pos] == '$')
- return parse_number(pos + 1, dest.constant);
+ return parse_number(pos + 1, &dest->constant_);
if (arg_[pos] == '%')
return parse_register(pos, dest);
if (isdigit(arg_[pos]) || arg_[pos] == '-') {
- pos = parse_number(pos, dest.deref_offset);
+ pos = parse_number(pos, &dest->deref_offset_);
if (arg_[pos] == '+') {
- pos = parse_identifier(pos + 1, dest.deref_ident);
- if (dest.deref_ident.empty())
+ pos = parse_identifier(pos + 1, &dest->deref_ident_);
+ if (dest->deref_ident().empty())
return -pos;
}
} else {
- pos = parse_identifier(pos, dest.deref_ident);
+ pos = parse_identifier(pos, &dest->deref_ident_);
}
if (arg_[pos] != '(')
return (arg_[pos] == ')') ? pos + 1 : -pos;
}
-ssize_t ArgumentParser::parse_1(ssize_t pos, Argument &dest) {
+ssize_t ArgumentParser::parse_1(ssize_t pos, Argument *dest) {
if (isdigit(arg_[pos]) || arg_[pos] == '-') {
int asize;
- ssize_t m = parse_number(pos, asize);
+ ssize_t m = parse_number(pos, &asize);
if (arg_[m] == '@') {
- dest.arg_size = asize;
+ dest->arg_size_ = asize;
return parse_expr(m + 1, dest);
}
}
fputc('\n', stderr);
}
-bool ArgumentParser::parse(Argument &dest) {
+bool ArgumentParser::parse(Argument *dest) {
if (done())
return false;
{"%al", 1}, {"%bl", 1}, {"%cl", 1}, {"%dl", 1}};
bool ArgumentParser_x64::validate_register(const std::string ®,
- int ®_size) {
+ int *reg_size) {
auto it = registers_.find(reg);
if (it == registers_.end())
return false;
- if (reg_size == 0)
- reg_size = it->second;
+ if (*reg_size == 0)
+ *reg_size = it->second;
return true;
}
}
const std::string ®ister_name, int constant,
int deref_offset, const std::string &deref_ident) {
USDT::Argument arg;
- REQUIRE(parser.parse(arg));
- REQUIRE(arg.arg_size == arg_size);
- REQUIRE(arg.register_name == register_name);
- REQUIRE(arg.constant == constant);
- REQUIRE(arg.deref_offset == deref_offset);
- REQUIRE(arg.deref_ident == deref_ident);
+ REQUIRE(parser.parse(&arg));
+ REQUIRE(arg.arg_size() == arg_size);
+ REQUIRE(arg.register_name() == register_name);
+ REQUIRE(arg.constant() == constant);
+ REQUIRE(arg.deref_offset() == deref_offset);
+ REQUIRE(arg.deref_ident() == deref_ident);
}
TEST_CASE("test usdt argument parsing", "[usdt]") {