> I wanted to write a small cocci patch to transform
> static const char *str = "...";
> into
> static const char * const str = "...";
>
> I used the following semantic patch:
>
> @@
> identifier str;
> expression E;
> @@
> -static const char *str
> +static const char * const str
> = E;
The patch below now supports this.
> So I did some more experimentation and it looks as if coccinelle does not
> like type qualifiers anywhere else except before the type. E.g. in C "const
> T" and "T const" are both legal C and have the same meaning.
Is there no ambiguity? Anyway, what I found in a grammar on the internet
was that const and volatile can appear after *, so that is what I have
added. There is still the limitation that you can only have one of const
and volatile per type. So eg volatile const int is still not accepted.
julia
---
diff --git a/parsing_cocci/parser_cocci_menhir.mly
b/parsing_cocci/parser_cocci_menhir.mly
index 978079b..790e653 100644
--- a/parsing_cocci/parser_cocci_menhir.mly
+++ b/parsing_cocci/parser_cocci_menhir.mly
@@ -724,8 +724,12 @@ all_basic_types:
| ty=non_signable_types { ty }
ctype:
- cv=ioption(const_vol) ty=all_basic_types m=list(TMul)
- { P.pointerify (P.make_cv cv ty) m }
+ cv=ioption(const_vol) ty=all_basic_types m=list(mul)
+ { List.fold_left
+ (function prev ->
+ function (star,cv) ->
+ P.make_cv cv (P.pointerify prev [star]))
+ (P.make_cv cv ty) m }
| r=Tsigned
{ Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,None)) }
| r=Tunsigned
@@ -735,6 +739,8 @@ ctype:
Ast0.wrap
(Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+mul: a=TMul b=ioption(const_vol) { (a,b) }
+
mctype:
| TMeta { tmeta_to_type $1 }
| ctype {$1}
diff --git a/parsing_c/unparse_cocci.ml b/parsing_c/unparse_cocci.ml
index d241f6e..82d6fd2 100644
--- a/parsing_c/unparse_cocci.ml
+++ b/parsing_c/unparse_cocci.ml
@@ -67,6 +67,9 @@ let print_option_prespace fn = function
let print_option_space fn = function
None -> ()
| Some x -> fn x; pr_space() in
+let print_option_prespace fn = function
+ None -> ()
+ | Some x -> pr_space(); fn x in
let print_between = Common.print_between in
let outdent _ = () (* should go to leftmost col, does nothing now *) in
@@ -454,7 +457,12 @@ and constant = function
and fullType ft =
match Ast.unwrap ft with
- Ast.Type(_,cv,ty) -> print_option_space (mcode const_vol) cv; typeC ty
+ Ast.Type(_,cv,ty) ->
+ (match Ast.unwrap ty with
+ Ast.Pointer(_,_) ->
+ typeC ty; print_option_prespace (mcode const_vol) cv
+ | _ -> print_option_space (mcode const_vol) cv; typeC ty)
+
| Ast.AsType(ty, asty) -> fullType ty
| Ast.DisjType _ -> failwith "can't be in plus"
| Ast.OptType(_) | Ast.UniqueType(_) ->
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)