/usr/lib/gdesklets/utils/actionparser.py is in gdesklets 0.36.1-7.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | #
# Parser for action strings.
#
# Grammar:
# ========
# S -> CALL | CALL , S
# CALL -> id : call ARGS | call ARGS
# ARGS -> (ARGS') | () | e
# ARGS' -> arg | arg , ARGS'
#
def parse(rest):
cmds = []
while (rest):
cmd, rest = _parse_command(rest)
cmds.append(cmd)
#end while
return cmds
def _parse_command(cmd):
inf = len(cmd) + 1
index1 = cmd.find("(")
if (index1 == -1): index1 = inf
index2 = cmd.find(",")
if (index2 == -1): index2 = inf
index = min(index1, index2)
parts, rest = cmd[:index], cmd[index:]
if (":" in parts):
ident, call = parts.split(":")
else:
ident, call = None, parts
if (rest and rest[0] == "("):
args, rest = _parse_args(rest)
else:
args = []
index = rest.find(",")
if (index != -1): rest = rest[index + 1:]
if (ident): ident = ident.strip()
call = call.strip()
return ((ident, call, args), rest)
def _parse_args(rest):
args = []
while (rest and rest[0] != ")"):
arg, rest = _parse_arg(rest[1:])
if (arg): args.append(arg)
#end while
return (args, rest[1:])
def _parse_arg(cmd):
# states are: 0 none
# 1 read " string
# 2 escape "
# 3 read ' string
# 4 escape '
# 5 escape
arg = ""
state = 0
for pos in xrange(len(cmd)):
c = cmd[pos]
if (state == 0):
if (c == "\""): arg += c; state = 1
elif (c == "'"): arg += c; state = 3
elif (c == "\\"): arg += c; state = 5
elif (c == ","): break
elif (c == ")"): break
else: arg += c
elif (state == 1):
if (c == "\""): arg += c; state = 0
elif (c == "\\"): arg += c; state = 2
else: arg += c
elif (state == 2): arg += c; state = 1
elif (state == 3):
if (c == "'"): arg += c; state = 0
elif (c == "\\"): arg += c; state = 4
else: arg += c
elif (state == 4): arg += c; state = 3
elif (state == 5): arg += c; state = 0
#end if
#end for
if (state != 0): print "Error"
rest = cmd[pos:]
arg = arg.strip().replace("\\,", ",").replace("\\)", ")")
return (arg, rest)
|