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

lexer: allow extglob wildcards as function names #771

Merged
merged 1 commit into from
Dec 11, 2021

Conversation

riacataquian
Copy link
Collaborator

the lexer assumes an extglob token if any of the wildcards expressions
(such as @, and +) are succeeded by a left parenthesis but that
proves to be an issue if the wildcard is used as a function name.

example input:

$ cat in.sh
@() {
  echo "$@";
}

bash and gosh comparison:

$ bash ./in.sh
hello
$ ./gosh in.sh
in.sh:5:1: "}" can only be used to close a block

given in.sh, gosh reports about a syntax error - this is because
a closing bracket is found while the lexer isn't assuming a function
block

fix the issue by assuming a function if one of the conditions below is
true:

  • if the expression is found at the beginning of the statement or if its
    preceded by a "function"
  • if ( is immediately succeeded by a ) - although this is a valid
    bash syntax, we'll operate on the likelihood that it is a function

fixes #739

@riacataquian riacataquian requested a review from mvdan December 8, 2021 17:04
Copy link
Owner

@mvdan mvdan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a more reliable condition would be:

when I see @, if I peek the next two bytes to be exactly (), don't tokenize as a glob.

The slight wrinkle there is that, currently, we only have peekByte which only looks one byte ahead. However, looking two bytes ahead is still reasonable - we only need to be worried about peeking a large or unbounded amount of bytes. So, mimicking peekByte, you can imagine a peekBytes call - taking a string, ensuring that the buffer has enough bytes for it via fill, and then comparing with e.g. bytes.HasPrefix.

syntax/lexer.go Outdated Show resolved Hide resolved
syntax/lexer.go Outdated Show resolved Hide resolved
@riacataquian
Copy link
Collaborator Author

Thanks for the helpful inputs @mvdan, I added peekBytes and it seems a lot cleaner now. I didn't put any restrictions to the length of the string in question/for comparison, thought I'd leave that to the discretion of the caller.

syntax/lexer.go Outdated Show resolved Hide resolved
the lexer assumes an extglob token if any of the wildcards expressions
(such as `@`, and `+`) are succeeded by a left parenthesis but that
proves to be an issue if the wildcard is used as a function name.

example input:
```
$ cat in.sh
@() {
  echo "$@";
}
```

`bash` and `gosh` comparison:
```
$ bash ./in.sh
hello
$ ./gosh in.sh
in.sh:5:1: "}" can only be used to close a block
```

given `in.sh`, gosh reports about a syntax error - this is because
a closing bracket is found while the lexer isn't assuming a function
block

fix the issue by assuming a function if one of the conditions below is
true:
* if the expression is found at the beginning of the statement or if its
  preceded by a "function"
* if `(` is immediately succeeded by a `)` - although this is a valid
  bash syntax, we'll operate on the likelihood that it is a function

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

Successfully merging this pull request may close these issues.

syntax: got "}" can only be used to close a block on a seemingly normal block
2 participants