Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support quoted strings as arguments to passes #4511

Open
gussmith23 opened this issue Jul 26, 2024 · 8 comments
Open

Support quoted strings as arguments to passes #4511

gussmith23 opened this issue Jul 26, 2024 · 8 comments

Comments

@gussmith23
Copy link

Feature Description

I'd like to be able to call a pass like

pass_name "some string" "some other string maybe having \"escaped quotes\""

and have the args list appear as

["pass_name", "some string", "some other string maybe having \"escaped quotes\""]

It currently seems like that might not be possible with the parser. Is that true, or am I missing something?

@povik
Copy link
Member

povik commented Jul 26, 2024

Related: #4429

@whitequark
Copy link
Member

IIRC this also affects bugpoint.

@gussmith23
Copy link
Author

It seems like this might be supported by the long_strings arg of next_token -- when true, it seems like next_token will grab an entire quoted string as one token (though it looks like it will break on escaped quotes \"). The relevant arg parsing code even sets next_token to true. However, despite this, quoted strings still don't seem to be parsed correctly. I'm wondering if there's bug here:

yosys/kernel/yosys.cc

Lines 201 to 208 in 960bca0

size_t pos_end = text.find_first_of(sep, pos_begin);
if (pos_end == std::string::npos)
pos_end = text.size();
std::string token = text.substr(pos_begin, pos_end-pos_begin);
text = text.substr(pos_end);
return token;

Essentially, if I pass command "some string", next_token will grab command as the first token and return "some string" (note the space) as the rest of the string. Because this string doesn't start with ", it won't trigger the long_strings case I think.

@KrystalDelusion
Copy link
Member

KrystalDelusion commented Jul 29, 2024

Oh huh, I was looking into this for log but it seemed like it was already being handled well enough at the kernel level. I certainly wasn't getting any issues of spaces at the start of strings in log.

I wonder if it's a difference between void Pass::call(RTLIL::Design *design, std::string command) and void Pass::call(RTLIL::Design *design, std::vector<std::string> args)? The former appears to skip spaces (and tabs) in the cmd_buf directly before attempting to grab the next token. That is probably why it works there but not other places?

yosys/kernel/register.cc

Lines 280 to 291 in 960bca0

for (auto c : cmd_buf) {
if (c == ' ' || c == '\t')
continue;
if (c == '\r' || c == '\n')
found_nl = true;
break;
}
if (found_nl) {
call(design, args);
args.clear();
}
tok = next_token(cmd_buf, " \t\r\n", true);

@gussmith23
Copy link
Author

Am I able to choose which one should be used when implementing a Pass? I override execute, which i assume is called by call.

@KrystalDelusion
Copy link
Member

That I do not know

@KrystalDelusion
Copy link
Member

The difference between which call is used is whether it is called with a string (which is the one you want for quote parsing), or as a list of strings (which does not). The only way to get the latter (as far as I can tell), is via tee, debug, and trace, all of which are called via the former and so have already had quotes parsed; or if your pass is a frontend, because for some reason frontends are handled slightly differently.

@KrystalDelusion
Copy link
Member

KrystalDelusion commented Aug 17, 2024

Oh actually backends also run their own arg parsing, and don't use call at all. See

yosys/kernel/register.cc

Lines 712 to 720 in 960bca0

void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command)
{
std::vector<std::string> args;
char *s = strdup(command.c_str());
for (char *p = strtok(s, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
args.push_back(p);
free(s);
backend_call(design, f, filename, args);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants