Skip to content

Commit

Permalink
helper functions for used arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
profezzorn committed Feb 24, 2024
1 parent 4f77640 commit f55ee75
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 1 deletion.
50 changes: 50 additions & 0 deletions common/arg_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,56 @@ class GetArgParser : public ArgParser {
const char* str_;
};

class GetUsedArgsParser : public ArgParser {
public:
GetUsedArgsParser(const char* data) : ArgParser(data) {
for (size_t i = 0; i < NELEM(used_args_); i++) {
used_args_[0] = 0;
}
}
const char* GetArg(int arg_num, const char* name, const char* default_value) override {
int arg = arg_num + offset_;
used_args_[arg >> 5] |= 1UL << (arg & 31);
return ArgParser::GetArg(arg_num, name, default_value);
}
void Shift(int words) override {
ArgParser::Shift(words);
offset_ += words;
}
int used() {
int ret = 0;
for (size_t i = 0; i < NELEM(used_args_); i++) {
ret += __builtin_popcount(used_args_[i]);
}
return ret;
}
int next(int ARG) {
for (size_t j = 0; j <= NELEM(used_args_); j++) {
int arg = (ARG + j) % NELEM(used_args_);
if (used_args_[arg >> 5] & (1UL << (arg & 31))) return arg;
}
}
int prev(int ARG) {
for (size_t j = 0; j <= NELEM(used_args_); j++) {
int arg = ((NELEM(used_args_) * 64) + ARG - j) % (NELEM(used_args_) * 32);
if (used_args_[arg >> 5] & (1UL << (arg & 31))) return arg;
}
}
int nth(int ARG) {
for (size_t arg = 0; arg <= NELEM(used_args_); arg++) {
if (used_args_[arg >> 5] & (1UL << (arg & 31))) {
if (ARG-- <= 0) {
return arg;
}
}
}
return 0;
}
private:
int offset_ = 0;
uint32_t used_args_[8];
};

class GetMaxArgParser : public ArgParser {
public:
GetMaxArgParser(const char* data) : ArgParser(data) {}
Expand Down
50 changes: 49 additions & 1 deletion styles/style_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class StyleParser : public CommandParser {
return ap.next();
}

// Returns true if the listed style refereces the specified argument.
// Returns the maximum argument used.
int MaxUsedArgument(const char* str) {
NamedStyle* style = FindStyle(str);
if (!style) return false;
Expand All @@ -162,6 +162,54 @@ class StyleParser : public CommandParser {
return ap.max_arg();
}

// Returns the number of used arguments.
int UsedArguments(const char* str) {
NamedStyle* style = FindStyle(str);
if (!style) return false;
GetUsedArgsParser ap(SkipWord(str));
CurrentArgParser = &ap;
delete style->style_allocator->make();
// Ignore the two "builtin" arguments
if (FirstWord(str, "builtin") && ap.used() <= 2) return 0;
return ap.used();
}

// Returns the next used argument.
int NextUsedArguments(const char* str, int arg) {
NamedStyle* style = FindStyle(str);
if (!style) return false;
GetUsedArgsParser ap(SkipWord(str));
CurrentArgParser = &ap;
delete style->style_allocator->make();
// Ignore the two "builtin" arguments
if (FirstWord(str, "builtin") && ap.used() <= 2) return 0;
return ap.next(arg);
}

// Returns the previous used argument.
int PrevUsedArguments(const char* str, int arg) {
NamedStyle* style = FindStyle(str);
if (!style) return false;
GetUsedArgsParser ap(SkipWord(str));
CurrentArgParser = &ap;
delete style->style_allocator->make();
// Ignore the two "builtin" arguments
if (FirstWord(str, "builtin") && ap.used() <= 2) return 0;
return ap.prev(arg);
}

// Returns Nth used argument.
int GetNthUsedArguments(const char* str, int arg) {
NamedStyle* style = FindStyle(str);
if (!style) return false;
GetUsedArgsParser ap(SkipWord(str));
CurrentArgParser = &ap;
delete style->style_allocator->make();
// Ignore the two "builtin" arguments
if (FirstWord(str, "builtin") && ap.used() <= 2) return 0;
return ap.nth(arg);
}

// Get the Nth argument of a style string.
// The output will be copied to |output|.
// If the string itself doesn't contain that argument, the style
Expand Down

0 comments on commit f55ee75

Please sign in to comment.