mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:07:44 +00:00
LibCore: Parse classless symbolic notation
This commit is contained in:
parent
736af8c7da
commit
12a6ec9292
1 changed files with 36 additions and 23 deletions
|
@ -13,7 +13,8 @@
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Reference,
|
Classes,
|
||||||
|
Operation,
|
||||||
Mode
|
Mode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,47 +49,59 @@ ErrorOr<FilePermissionsMask> FilePermissionsMask::from_symbolic_notation(StringV
|
||||||
{
|
{
|
||||||
auto mask = FilePermissionsMask();
|
auto mask = FilePermissionsMask();
|
||||||
|
|
||||||
u8 state = State::Reference;
|
u8 state = State::Classes;
|
||||||
u8 classes = 0;
|
u8 classes = 0;
|
||||||
u8 operation = 0;
|
u8 operation = 0;
|
||||||
|
|
||||||
for (auto ch : string) {
|
for (auto ch : string) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case State::Reference: {
|
case State::Classes: {
|
||||||
// one or more [ugoa] terminated by one operator [+-=]
|
// one or more [ugoa] terminated by one operator [+-=]
|
||||||
if (ch == 'u')
|
if (ch == 'u') {
|
||||||
classes |= ClassFlag::User;
|
classes |= ClassFlag::User;
|
||||||
else if (ch == 'g')
|
state = State::Operation;
|
||||||
|
break;
|
||||||
|
} else if (ch == 'g') {
|
||||||
classes |= ClassFlag::Group;
|
classes |= ClassFlag::Group;
|
||||||
else if (ch == 'o')
|
state = State::Operation;
|
||||||
|
break;
|
||||||
|
} else if (ch == 'o') {
|
||||||
classes |= ClassFlag::Other;
|
classes |= ClassFlag::Other;
|
||||||
else if (ch == 'a')
|
state = State::Operation;
|
||||||
|
break;
|
||||||
|
} else if (ch == 'a') {
|
||||||
classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other;
|
classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other;
|
||||||
else {
|
state = State::Operation;
|
||||||
if (classes == 0)
|
break;
|
||||||
return Error::from_string_literal("invalid access class: expected 'u', 'g', 'o' or 'a' "sv);
|
|
||||||
|
|
||||||
if (ch == '+')
|
|
||||||
operation = Operation::Add;
|
|
||||||
else if (ch == '-')
|
|
||||||
operation = Operation::Remove;
|
|
||||||
else if (ch == '=')
|
|
||||||
operation = Operation::Assign;
|
|
||||||
else
|
|
||||||
return Error::from_string_literal("invalid operation: expected '+', '-' or '='"sv);
|
|
||||||
|
|
||||||
state = State::Mode;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case State::Operation: {
|
||||||
|
if (ch == '+')
|
||||||
|
operation = Operation::Add;
|
||||||
|
else if (ch == '-')
|
||||||
|
operation = Operation::Remove;
|
||||||
|
else if (ch == '=')
|
||||||
|
operation = Operation::Assign;
|
||||||
|
else if (classes == 0)
|
||||||
|
return Error::from_string_literal("invalid access class: expected 'u', 'g', 'o' or 'a' "sv);
|
||||||
|
else
|
||||||
|
return Error::from_string_literal("invalid operation: expected '+', '-' or '='"sv);
|
||||||
|
|
||||||
|
// if an operation was specified without a class, assume all
|
||||||
|
if (classes == 0)
|
||||||
|
classes = ClassFlag::User | ClassFlag::Group | ClassFlag::Other;
|
||||||
|
|
||||||
|
state = State::Mode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case State::Mode: {
|
case State::Mode: {
|
||||||
// one or more [rwx] terminated by a comma
|
// one or more [rwx] terminated by a comma
|
||||||
|
|
||||||
// End of mode part, expect reference next
|
// End of mode part, expect class next
|
||||||
if (ch == ',') {
|
if (ch == ',') {
|
||||||
state = State::Reference;
|
state = State::Classes;
|
||||||
classes = operation = 0;
|
classes = operation = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue