Coccinelle release 0.2.5-rc8
[bpt/coccinelle.git] / parsing_cocci / lexer_cocci.mll
index d2a4ec8..0d4f55a 100644 (file)
@@ -1,27 +1,7 @@
 (*
- * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
- * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
- * This file is part of Coccinelle.
- *
- * Coccinelle is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, according to version 2 of the License.
- *
- * Coccinelle is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
- *
- * The authors reserve the right to distribute this or future versions of
- * Coccinelle under other licenses.
- *)
-
-
-(*
- * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
+ * Copyright 2010, INRIA, University of Copenhagen
+ * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
+ * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
  * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
  * This file is part of Coccinelle.
  *
@@ -217,7 +197,8 @@ let id_tokens lexbuf =
   let in_iso = !Data.in_iso in
   let in_prolog = !Data.in_prolog in
   match s with
-    "identifier" when in_meta -> check_arity_context_linetype s; TIdentifier
+    "metavariable" when in_meta -> check_arity_context_linetype s; TMetavariable
+  | "identifier" when in_meta -> check_arity_context_linetype s; TIdentifier
   | "type" when in_meta ->       check_arity_context_linetype s; TType
   | "parameter" when in_meta ->  check_arity_context_linetype s; TParameter
   | "constant"  when in_meta ->  check_arity_context_linetype s; TConstant
@@ -225,6 +206,10 @@ let id_tokens lexbuf =
       check_arity_context_linetype s; TGenerated
   | "expression" when in_meta || in_rule_name ->
       check_arity_context_linetype s; TExpression
+  | "declaration" when in_meta || in_rule_name ->
+      check_arity_context_linetype s; TDeclaration
+  | "field" when in_meta || in_rule_name ->
+      check_arity_context_linetype s; TField
   | "initialiser" when in_meta || in_rule_name ->
       check_arity_context_linetype s; TInitialiser
   | "initializer" when in_meta || in_rule_name ->
@@ -273,6 +258,9 @@ let id_tokens lexbuf =
   | "float" ->      Tfloat    linetype
   | "long" ->       Tlong     linetype
   | "void" ->       Tvoid     linetype
+  | "size_t" ->     Tsize_t   linetype
+  | "ssize_t" ->    Tssize_t  linetype
+  | "ptrdiff_t" ->  Tptrdiff_t linetype
   (* in_meta is only for the first keyword; drop it now to allow any type
      name *)
   | "struct" ->     Data.saw_struct := true; Tstruct   linetype
@@ -306,14 +294,16 @@ let id_tokens lexbuf =
 
   | "sizeof" ->     TSizeof   linetype
 
-  | "Expression"       -> TIsoExpression
-  | "ArgExpression"    -> TIsoArgExpression
-  | "TestExpression"   -> TIsoTestExpression
-  | "ToTestExpression" -> TIsoToTestExpression
-  | "Statement"        -> TIsoStatement
-  | "Declaration"      -> TIsoDeclaration
-  | "Type"             -> TIsoType
-  | "TopLevel"         -> TIsoTopLevel
+  | "Expression"       when !Data.in_iso -> TIsoExpression
+  | "ArgExpression"    when !Data.in_iso -> TIsoArgExpression
+  | "TestExpression"   when !Data.in_iso -> TIsoTestExpression
+  | "ToTestExpression" when !Data.in_iso -> TIsoToTestExpression
+  | "Statement"        when !Data.in_iso -> TIsoStatement
+  | "Declaration"      when !Data.in_iso -> TIsoDeclaration
+  | "Type"             when !Data.in_iso -> TIsoType
+  | "TopLevel"         when !Data.in_iso -> TIsoTopLevel
+
+  | "_" when !Data.in_meta -> TUnderscore
 
   | s -> check_var s linetype
 
@@ -342,6 +332,10 @@ let init _ =
   Hashtbl.clear iterator_names;
   Hashtbl.clear declarer_names;
   let get_name (_,x) = x in
+  Data.add_meta_meta :=
+    (fun name pure ->
+      let fn clt = TMeta(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
   Data.add_id_meta :=
     (fun name constraints pure ->
       let fn clt = TMetaId(name,constraints,pure,clt) in
@@ -398,6 +392,18 @@ let init _ =
     (function name -> function lenname -> function pure ->
       let fn clt = TMetaExpList(name,lenname,pure,clt) in
       Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_decl_meta :=
+    (function name -> function pure ->
+      let fn clt = TMetaDecl(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_field_meta :=
+    (function name -> function pure ->
+      let fn clt = TMetaField(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_field_list_meta :=
+    (function name -> function lenname -> function pure ->
+      let fn clt = TMetaFieldList(name,lenname,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
   Data.add_stm_meta :=
     (function name -> function pure ->
       let fn clt = TMetaStm(name,pure,clt) in
@@ -511,9 +517,17 @@ rule token = parse
   | "//" [^ '\n']* {
     match !current_line_type with
       (D.PLUS,_,_) | (D.PLUSPLUS,_,_) ->
+       start_line true;
        TPragma (Ast.Indent (tok lexbuf), get_current_line_type lexbuf)
     | _ -> start_line false; token lexbuf }
 
+  | "__attribute__" [' ' '\t']* "((" _* "))"
+   { match !current_line_type with
+      (D.PLUS,_,_) | (D.PLUSPLUS,_,_) ->
+       start_line true;
+       TPragma (Ast.Space (tok lexbuf), get_current_line_type lexbuf)
+    | _ -> failwith "attributes only allowedin + code" }
+
   | "@@" { start_line true; TArobArob }
   | "@"  { pass_zero();
           if !Data.in_rule_name or not !current_line_started
@@ -581,7 +595,7 @@ rule token = parse
           else if !Data.in_meta
          then TBang0
           else (add_current_line_type D.UNIQUE; token lexbuf) }
-  | "(" { if not !col_zero
+  | "(" { if !Data.in_meta or not !col_zero
          then (start_line true; TOPar (get_current_line_type lexbuf))
           else
             (start_line true; check_context_linetype (tok lexbuf);
@@ -670,14 +684,25 @@ rule token = parse
   | "||"           { start_line true; TOrLog  (get_current_line_type lexbuf) }
 
   | ">>"           { start_line true;
-                    TShOp(Ast.DecRight,get_current_line_type lexbuf) }
+                    TShROp(Ast.DecRight,get_current_line_type lexbuf) }
   | "<<"           { start_line true;
-                    TShOp(Ast.DecLeft,get_current_line_type lexbuf) }
+                    TShLOp(Ast.DecLeft,get_current_line_type lexbuf) }
 
   | "&"            { start_line true; TAnd    (get_current_line_type lexbuf) }
   | "^"            { start_line true; TXor(get_current_line_type lexbuf) }
 
   | "##"            { start_line true; TCppConcatOp }
+  | (( ("#" [' ' '\t']*  "undef" [' ' '\t']+)) as def)
+    ( (letter (letter |digit)*) as ident)
+      { start_line true;
+       let (arity,line,lline,offset,col,strbef,straft,pos) as lt =
+         get_current_line_type lexbuf in
+       let off = String.length def in
+       (* -1 in the code below because the ident is not at the line start *)
+       TUndef
+         (lt,
+          check_var ident
+            (arity,line,lline,offset+off,col+off,[],[],Ast0.NoMetaPos)) }
   | (( ("#" [' ' '\t']*  "define" [' ' '\t']+)) as def)
     ( (letter (letter |digit)*) as ident)
       { start_line true;