Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
f279df55
Commit
f279df55
authored
Mar 02, 2018
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for optional arguments to VMOD functions.
parent
e446c076
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
104 additions
and
18 deletions
+104
-18
vcc_expr.c
lib/libvcc/vcc_expr.c
+37
-4
vmodtool.py
lib/libvcc/vmodtool.py
+67
-14
No files found.
lib/libvcc/vcc_expr.c
View file @
f279df55
...
...
@@ -406,6 +406,8 @@ struct func_arg {
const
char
*
name
;
const
char
*
val
;
struct
expr
*
result
;
int
avail
;
int
optional
;
VTAILQ_ENTRY
(
func_arg
)
list
;
};
...
...
@@ -449,6 +451,7 @@ vcc_do_arg(struct vcc *tl, struct func_arg *fa)
assert
(
e2
->
fmt
==
fa
->
type
);
fa
->
result
=
e2
;
}
fa
->
avail
=
1
;
}
static
void
...
...
@@ -462,6 +465,9 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
VTAILQ_HEAD
(,
func_arg
)
head
;
struct
token
*
t1
;
const
struct
vjsn_val
*
vv
,
*
vvp
;
const
char
*
sa
;
char
ssa
[
64
];
char
ssa2
[
64
];
CAST_OBJ_NOTNULL
(
vv
,
priv
,
VJSN_VAL_MAGIC
);
assert
(
vv
->
type
==
VJSN_ARRAY
);
...
...
@@ -471,6 +477,15 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
vv
=
VTAILQ_NEXT
(
vv
,
list
);
cfunc
=
vv
->
value
;
vv
=
VTAILQ_NEXT
(
vv
,
list
);
sa
=
vv
->
value
;
if
(
*
sa
==
'\0'
)
{
sa
=
NULL
;
}
else
{
bprintf
(
ssa
,
"args_%u"
,
tl
->
unique
++
);
VSB_printf
(
tl
->
curproc
->
prologue
,
" %s %s;
\n
"
,
sa
,
ssa
);
sa
=
ssa
;
}
vv
=
VTAILQ_NEXT
(
vv
,
list
);
SkipToken
(
tl
,
'('
);
if
(
extra
==
NULL
)
extra
=
""
;
...
...
@@ -504,6 +519,10 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
}
}
}
if
(
sa
!=
NULL
&&
vvp
!=
NULL
&&
vvp
->
type
==
VJSN_TRUE
)
{
fa
->
optional
=
1
;
vvp
=
VTAILQ_NEXT
(
vvp
,
list
);
}
AZ
(
vvp
);
}
...
...
@@ -551,23 +570,37 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv,
SkipToken
(
tl
,
','
);
}
e1
=
vcc_mk_expr
(
rfmt
,
"%s(ctx%s
\v
+"
,
cfunc
,
extra
);
if
(
sa
!=
NULL
)
e1
=
vcc_mk_expr
(
rfmt
,
"%s(ctx%s,
\v
+(
\n
"
,
cfunc
,
extra
);
else
e1
=
vcc_mk_expr
(
rfmt
,
"%s(ctx%s
\v
+"
,
cfunc
,
extra
);
VTAILQ_FOREACH_SAFE
(
fa
,
&
head
,
list
,
fa2
)
{
if
(
fa
->
optional
)
VSB_printf
(
tl
->
curproc
->
prologue
,
" %s.valid_%s = %d;
\n
"
,
sa
,
fa
->
name
,
fa
->
avail
);
if
(
fa
->
result
==
NULL
&&
fa
->
type
==
ENUM
&&
fa
->
val
!=
NULL
)
vcc_do_enum
(
tl
,
fa
,
strlen
(
fa
->
val
),
fa
->
val
);
if
(
fa
->
result
==
NULL
&&
fa
->
val
!=
NULL
)
fa
->
result
=
vcc_mk_expr
(
fa
->
type
,
"%s"
,
fa
->
val
);
if
(
fa
->
result
!=
NULL
)
if
(
fa
->
result
!=
NULL
&&
sa
!=
NULL
)
{
bprintf
(
ssa2
,
"
\v
1%s.%s =
\v
2,
\n
"
,
sa
,
fa
->
name
);
e1
=
vcc_expr_edit
(
tl
,
e1
->
fmt
,
ssa2
,
e1
,
fa
->
result
);
}
else
if
(
fa
->
result
!=
NULL
)
{
e1
=
vcc_expr_edit
(
tl
,
e1
->
fmt
,
"
\v
1,
\n\v
2"
,
e1
,
fa
->
result
);
else
{
}
else
if
(
!
fa
->
optional
)
{
VSB_printf
(
tl
->
sb
,
"Argument '%s' missing
\n
"
,
fa
->
name
);
vcc_ErrWhere
(
tl
,
tl
->
t
);
}
free
(
fa
);
}
*
e
=
vcc_expr_edit
(
tl
,
e1
->
fmt
,
"
\v
1
\n
)
\v
-"
,
e1
,
NULL
);
if
(
sa
!=
NULL
)
{
bprintf
(
ssa2
,
"
\v
1&%s
\v
-
\n
))"
,
sa
);
*
e
=
vcc_expr_edit
(
tl
,
e1
->
fmt
,
ssa2
,
e1
,
NULL
);
}
else
{
*
e
=
vcc_expr_edit
(
tl
,
e1
->
fmt
,
"
\v
1
\n
)
\v
-"
,
e1
,
NULL
);
}
SkipToken
(
tl
,
')'
);
}
...
...
lib/libvcc/vmodtool.py
View file @
f279df55
...
...
@@ -199,6 +199,7 @@ class ctype(object):
self
.
nm
=
None
self
.
defval
=
None
self
.
spec
=
None
self
.
opt
=
False
self
.
vt
=
wl
.
pop
(
0
)
self
.
ct
=
ctypes
.
get
(
self
.
vt
)
...
...
@@ -287,6 +288,8 @@ class arg(ctype):
def
json
(
self
,
jl
):
jl
.
append
([
self
.
vt
,
self
.
nm
,
self
.
defval
,
self
.
spec
])
if
self
.
opt
:
jl
[
-
1
]
.
append
(
True
)
while
jl
[
-
1
][
-
1
]
is
None
:
jl
[
-
1
]
.
pop
(
-
1
)
...
...
@@ -313,7 +316,7 @@ def lex(l):
if
s
==
0
and
c
in
(
' '
,
'
\t
'
,
'
\n
'
,
'
\r
'
):
continue
if
s
==
0
and
c
in
(
'
('
,
'{'
,
'}'
,
')
'
,
','
,
'='
):
if
s
==
0
and
c
in
(
'
['
,
'('
,
'{'
,
'}'
,
')'
,
']
'
,
','
,
'='
):
wl
.
append
(
c
)
elif
s
==
0
and
c
in
(
'"'
,
"'"
):
sep
=
c
...
...
@@ -330,10 +333,10 @@ def lex(l):
wl
[
-
1
]
+=
c
s
=
1
else
:
err
(
"Syntax error at char
"
,
i
,
"'
%
s'"
%
c
,
warn
=
False
)
err
(
"Syntax error at char
%
d '
%
s'"
%
(
i
,
c
)
,
warn
=
False
)
if
s
!=
0
:
err
(
"Syntax error at char
"
,
i
,
"'
%
s'"
%
c
,
warn
=
False
)
err
(
"Syntax error at char
%
d '
%
s'"
%
(
i
,
c
)
,
warn
=
False
)
return
wl
#######################################################################
...
...
@@ -344,6 +347,7 @@ class prototype(object):
self
.
st
=
st
self
.
obj
=
None
self
.
args
=
[]
self
.
argstruct
=
False
wl
=
lex
(
st
.
line
[
1
])
if
retval
:
...
...
@@ -371,13 +375,30 @@ class prototype(object):
wl
[
-
1
]
=
','
names
=
{}
n
=
0
while
len
(
wl
)
>
0
:
n
+=
1
x
=
wl
.
pop
(
0
)
if
x
!=
','
:
err
(
"Expected ',' found '
%
s'"
%
x
,
warn
=
False
)
if
len
(
wl
)
==
0
:
break
t
=
arg
(
wl
,
names
,
st
.
vcc
.
enums
,
','
)
if
wl
[
0
]
==
'['
:
wl
.
pop
(
0
)
t
=
arg
(
wl
,
names
,
st
.
vcc
.
enums
,
']'
)
if
t
.
nm
is
None
:
err
(
"Optional arguments must have names"
,
warn
=
False
)
t
.
opt
=
True
x
=
wl
.
pop
(
0
)
if
x
!=
']'
:
err
(
"Expected ']' found '
%
s'"
%
x
,
warn
=
False
)
self
.
argstruct
=
True
else
:
t
=
arg
(
wl
,
names
,
st
.
vcc
.
enums
,
','
)
if
t
.
nm
is
None
:
t
.
nm2
=
"arg
%
d"
%
n
else
:
t
.
nm2
=
t
.
nm
self
.
args
.
append
(
t
)
def
vcl_proto
(
self
,
short
,
pfx
=
""
):
...
...
@@ -406,6 +427,8 @@ class prototype(object):
t
+=
" "
+
i
.
nm
if
i
.
defval
is
not
None
:
t
+=
"="
+
i
.
defval
if
i
.
opt
:
t
=
"["
+
t
+
"]"
ll
.
append
(
t
)
t
=
",@"
.
join
(
ll
)
if
len
(
s
+
t
)
>
68
and
not
short
:
...
...
@@ -440,8 +463,11 @@ class prototype(object):
def
proto
(
self
,
args
,
name
):
s
=
self
.
retval
.
ct
+
" "
+
name
+
'('
ll
=
args
for
i
in
self
.
args
:
ll
.
append
(
i
.
ct
)
if
self
.
argstruct
:
ll
.
append
(
self
.
argstructname
()
+
"*"
)
else
:
for
i
in
self
.
args
:
ll
.
append
(
i
.
ct
)
s
+=
", "
.
join
(
ll
)
return
s
+
');'
...
...
@@ -449,21 +475,49 @@ class prototype(object):
tn
=
'td_'
+
self
.
st
.
vcc
.
modname
+
'_'
+
self
.
cname
()
return
"typedef "
+
self
.
proto
(
args
,
name
=
tn
)
def
argstructname
(
self
):
return
"struct
%
s_arg"
%
self
.
cname
(
True
)
def
argstructure
(
self
):
s
=
"
\n
"
+
self
.
argstructname
()
+
" {
\n
"
for
i
in
self
.
args
:
if
i
.
opt
:
assert
i
.
nm
is
not
None
s
+=
"
\t
char
\t\t\t
valid_
%
s;
\n
"
%
i
.
nm
for
i
in
self
.
args
:
s
+=
"
\t
"
+
i
.
ct
if
len
(
i
.
ct
)
<
8
:
s
+=
"
\t
"
if
len
(
i
.
ct
)
<
16
:
s
+=
"
\t
"
s
+=
"
\t
"
+
i
.
nm2
+
";
\n
"
s
+=
"};
\n
"
return
s
def
cstuff
(
self
,
args
,
where
):
s
=
""
if
where
==
'h'
:
s
=
self
.
proto
(
args
,
self
.
cname
(
True
))
if
self
.
argstruct
:
s
+=
self
.
argstructure
()
s
+=
lwrap
(
self
.
proto
(
args
,
self
.
cname
(
True
)))
elif
where
==
'c'
:
s
=
self
.
typedef
(
args
)
s
+=
lwrap
(
self
.
typedef
(
args
)
)
elif
where
==
'o'
:
s
=
self
.
typedef
(
args
)
if
self
.
argstruct
:
s
+=
self
.
argstructure
()
s
+=
lwrap
(
self
.
typedef
(
args
))
else
:
assert
False
return
lwrap
(
s
)
return
s
def
json
(
self
,
jl
,
cfunc
):
ll
=
[]
self
.
retval
.
json
(
ll
)
ll
.
append
(
'Vmod_
%
s_Func.
%
s'
%
(
self
.
st
.
vcc
.
modname
,
cfunc
))
if
self
.
argstruct
:
ll
.
append
(
self
.
argstructname
())
else
:
ll
.
append
(
""
)
for
i
in
self
.
args
:
i
.
json
(
ll
)
jl
.
append
(
ll
)
...
...
@@ -632,8 +686,7 @@ class s_function(stanza):
self
.
vcc
.
contents
.
append
(
self
)
def
cstuff
(
self
,
fo
,
where
):
if
where
in
(
'h'
,
'c'
):
fo
.
write
(
self
.
proto
.
cstuff
([
'VRT_CTX'
],
where
))
fo
.
write
(
self
.
proto
.
cstuff
([
'VRT_CTX'
],
where
))
def
cstruct
(
self
,
fo
,
define
):
if
define
:
...
...
@@ -948,13 +1001,13 @@ class vcc(object):
for
i
in
self
.
contents
:
if
type
(
i
)
==
s_object
:
i
.
cstuff
(
fo
,
'c'
)
i
.
cstuff
(
fx
,
'
c
'
)
i
.
cstuff
(
fx
,
'
o
'
)
fx
.
write
(
"/* Functions */
\n
"
)
for
i
in
self
.
contents
:
if
type
(
i
)
==
s_function
:
i
.
cstuff
(
fo
,
'c'
)
i
.
cstuff
(
fx
,
'
c
'
)
i
.
cstuff
(
fx
,
'
o
'
)
csn
=
"Vmod_
%
s_Func"
%
self
.
modname
scsn
=
"struct "
+
csn
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment