> 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)

Reply via email to