(* * bibtex2html - A BibTeX to HTML translator * Copyright (C) 1997-2000 Jean-Christophe Filliātre and Claude Marché * * This software is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation. * * This software 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 version 2 for more details * (enclosed in the file GPL). *) (*i $Id: condition.ml,v 1.12 2004/07/06 15:22:33 marche Exp $ i*) open Printf;; type constante = | Key | Entrytype | Field of string | Cte of string ;; type condition = | True | False | And of condition * condition | Or of condition * condition | Not of condition | Comp of constante * string * constante | Match of constante * Str.regexp | Exists of string ;; exception Unavailable;; let evaluate_constante entrytype key fields = function Key -> key | Entrytype -> entrytype | Field(f) -> begin try match List.assoc f fields with | [Bibtex.String(v)] -> Latex_accents.normalize false v | [Bibtex.Id(v)] -> v | _ -> raise Unavailable with Not_found -> raise Unavailable end | Cte(x) -> Latex_accents.normalize false x ;; let eval_comp v1 op v2 = match op with "=" -> v1 = v2 | "<>" -> v1 <> v2 | _ -> let n1 = int_of_string v1 and n2 = int_of_string v2 in match op with ">" -> n1 > n2 | "<" -> n1 < n2 | ">=" -> n1 >= n2 | "<=" -> n1 <= n2 | _ -> assert false ;; let rec evaluate_rec entrytype key fields = function | True -> true | False -> false | And(c1,c2) -> if evaluate_rec entrytype key fields c1 then evaluate_rec entrytype key fields c2 else false | Or(c1,c2) -> if evaluate_rec entrytype key fields c1 then true else evaluate_rec entrytype key fields c2 | Not(c) -> not (evaluate_rec entrytype key fields c) | Comp(c1,op,c2) -> begin try let v1 = evaluate_constante entrytype key fields c1 and v2 = evaluate_constante entrytype key fields c2 in try eval_comp v1 op v2 with Failure "int_of_string" -> if not !Options.quiet then begin eprintf "Warning: cannot compare non-numeric values "; eprintf "%s and %s in entry %s\n" v1 v2 key end; if !Options.warn_error then exit 2; false with Unavailable -> false end | Match(c,r) -> begin try let v = evaluate_constante entrytype key fields c in let _ = Str.search_forward r v 0 in true with Not_found -> false | Unavailable -> false end | Exists(f) -> begin try let _ = List.assoc f fields in true with Not_found -> false end ;; let evaluate_cond entrytype key fields c = try evaluate_rec entrytype key fields c with Not_found -> assert false ;; let string_of_constante = function Key -> "(key)" | Entrytype -> "(entrytype)" | Field(f) -> f | Cte(x) -> "\"" ^ x ^ "\"" ;; let rec print = function | True -> printf "true" | False -> printf "false" | And(c1,c2) -> printf "("; print c1; printf " and "; print c2; printf ")" | Or(c1,c2) -> printf "("; print c1; printf " or "; print c2; printf ")" | Not(c) -> printf "(not "; print c; printf ")" | Comp(c1,op,c2) -> printf "%s %s %s" (string_of_constante c1) op (string_of_constante c2) | Match(c,s) -> printf "%s : (regexp)" (string_of_constante c) | Exists(f) -> printf "exists %s" f ;;