Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117751699
grammar.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
grammar.c
View Options
/*
* grammar.c
*
* Created on: Nov 6, 2014
* Author: James Cassell
*/
#ifdef HAVE_CONFIG_H
#include
<config.h>
#endif
#include
"grammar.h"
#include
"xmalloc.h"
EXPORTED
int
is_identifier
(
char
*
s
)
{
/* identifier = (ALPHA / "_") *(ALPHA / DIGIT / "_") */
int
i
=
0
;
while
(
s
&&
s
[
i
])
{
if
(
s
[
i
]
==
'_'
||
(
s
[
i
]
>=
'a'
&&
s
[
i
]
<=
'z'
)
||
(
s
[
i
]
>=
'A'
&&
s
[
i
]
<=
'Z'
)
||
(
i
&&
(
s
[
i
]
>=
'0'
&&
s
[
i
]
<=
'9'
)))
{
i
++
;
}
else
{
return
0
;
}
}
return
1
;
}
EXPORTED
int
is_number
(
char
*
s
)
{
char
*
tail
;
if
(
s
&&
*
s
&&
(
strtol
(
s
,
&
tail
,
10
)
||
!*
tail
)
&&
!*
tail
)
{
return
1
;
}
return
0
;
}
/* TODO: implement parse_string() with a proper yacc/bison lexer/parser */
EXPORTED
char
*
parse_string
(
const
char
*
s
,
variable_list_t
*
vars
)
{
/* protect against being called with no string - this is possible in some places */
if
(
!
s
)
return
NULL
;
/*
* variable-ref = "${" [namespace] variable-name "}"
* namespace = identifier "." *sub-namespace
* sub-namespace = variable-name "."
* variable-name = num-variable / identifier
* num-variable = 1*DIGIT
* identifier = (ALPHA / "_") *(ALPHA / DIGIT / "_")
*/
strarray_t
stringparts
=
STRARRAY_INITIALIZER
;
variable_list_t
*
variable
=
NULL
;
char
*
test_str
;
int
is_match_var
;
int
match_var
;
int
fail
=
0
;
strarray_append
(
&
stringparts
,
s
);
test_str
=
stringparts
.
data
[
stringparts
.
count
-1
];
while
(
test_str
&&
*
test_str
)
{
char
*
variable_ref_begin
,
*
variable_ref_end
;
/* find the beginning of a variable-ref */
while
(
*
test_str
&&
*
(
test_str
+
1
)
&&
!
(
'$'
==
*
test_str
&&
'{'
==
*
(
test_str
+
1
)))
{
test_str
++
;
}
/* if we've reached the end of the string, we're done */
if
(
!
(
*
test_str
&&
*
(
test_str
+
1
)))
{
break
;
}
/* save the beginning of the variable-ref */
variable_ref_begin
=
variable_ref_end
=
test_str
;
test_str
+=
2
;
variable_ref_end
+=
2
;
/* find the end of the variable-ref */
while
(
*
variable_ref_end
&&
!
(
'}'
==
*
variable_ref_end
))
{
variable_ref_end
++
;
}
/* if we've reached the end of the string, we're done */
if
(
!*
variable_ref_end
)
{
break
;
}
/* create a null-terminated string for comparison */
*
variable_ref_end
=
'\0'
;
/* check if the string is a number */
is_match_var
=
is_number
(
test_str
);
/* if we've found a valid variable, add its value to stringparts */
if
(
is_identifier
(
test_str
)
||
is_match_var
)
{
/* capture the match_var variable number */
match_var
=
strtol
(
test_str
,
NULL
,
10
);
/* NULL-terminate the previous stringpart */
*
variable_ref_begin
=
'\0'
;
/* attempt to find the variable */
if
(
is_match_var
)
{
variable
=
varlist_select
(
vars
,
VL_MATCH_VARS
);
if
(
match_var
>=
variable
->
var
->
count
)
{
variable
=
NULL
;
}
}
else
{
variable
=
varlist_select
(
vars
,
test_str
);
}
/* add the value of the requested variable to stringparts if
* the variable is found
*/
if
(
variable
)
{
char
*
temp
;
if
(
is_match_var
)
{
temp
=
xstrdup
(
variable
->
var
->
data
[
match_var
]);
}
else
{
temp
=
strarray_join
(
variable
->
var
,
" "
);
}
if
(
temp
)
{
strarray_append
(
&
stringparts
,
temp
);
free
(
temp
);
}
}
/* continue search for variable-ref's after the current one */
test_str
=
variable_ref_end
+
1
;
/* add the remainder of the original string to stringparts */
if
(
*
test_str
)
{
strarray_append
(
&
stringparts
,
test_str
);
test_str
=
stringparts
.
data
[
stringparts
.
count
-1
];
}
}
else
{
/* first check if this is a namespace, which we don't yet support.
RFC 5229, Sieve: Variables Extension, Section 3. Interpretation of Strings:
References to namespaces without a prior require statement for the
relevant extension MUST cause an error.
*/
{
char
*
dot
;
if
((
dot
=
strchr
(
test_str
,
'.'
)))
{
*
dot
=
'\0'
;
if
(
is_identifier
(
test_str
))
{
fail
=
1
;
}
else
{
*
dot
=
'.'
;
}
}
}
/* if we haven't found a valid variable, restore the overwritten
* character
*/
*
variable_ref_end
=
'}'
;
/* continue the search after the non-valid identifier */
test_str
=
variable_ref_begin
+
2
;
}
}
if
((
test_str
=
strarray_join
(
&
stringparts
,
""
)))
{
strarray_appendm
(
varlist_select
(
vars
,
VL_PARSED_STRINGS
)
->
var
,
test_str
);
}
else
{
test_str
=
xstrdup
(
""
);
strarray_appendm
(
varlist_select
(
vars
,
VL_PARSED_STRINGS
)
->
var
,
test_str
);
}
strarray_fini
(
&
stringparts
);
/* TODO: test this in the sieve parser, not at script runtime */
if
(
0
&&
fail
)
{
free
(
test_str
);
test_str
=
NULL
;
}
return
test_str
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Apr 4, 3:22 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822391
Default Alt Text
grammar.c (5 KB)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline