Skip to content
Commits on Source (10)
spatch
spatch.opt
scripts/spatch
scripts/spatch.opt
scripts/spatch.byte
*.so
*.cm[aiox]
*.cmx[as]
*.cmt
*.cmti
*.[ao]
*.annot
*.pyc
*.d
*.d.opt
*~
.depend
version.ml
/configure
Makefile.config
Makefile.override
Makefile.local
result
globals/config.ml
python/pycocci.ml
commons/commands.ml
globals/regexp.ml
ocaml/prepare_ocamlcocci.ml
parsing_cocci/lexer_cli.ml
scripts/spatch.sh
scripts/spatch
scripts/spatch.byte
scripts/spatch.opt
tests/SCORE_actual.sexp
tests/SCORE_best_of_both.sexp
tests/SCORE_expected_orig.sexp
tests/SCORE_expected.sexp
tests/SCORE_expected.sexp.save
config.log
config.status
autom4te.cache
aclocal.m4
*.native
*.byte
*.d.native
*.p.byte
.mascotrc
description-pak
*.current
/bundles/pyml/pyml-current/pyml_arch.ml
/bundles/stdcompat/*.ml
/bundles/stdcompat/*.mli
/bundles/stdcompat/stdcompat-*/META
/bundles/stdcompat/stdcompat-*/Makefile
/bundles/stdcompat/stdcompat-*/*.ml
/bundles/stdcompat/stdcompat-*/*.mli
/bundles/stdcompat/doc/
/bundles/menhirLib/menhir-20171013/
#Source directories
S commons
S commons/ocamlextra
S ctl
S engine
S extra
S globals
S ocaml
S parsing_c
S parsing_cocci
S popl
S popl09
S python
# Build directories
B commons
B commons/ocamlextra
B ctl
B engine
B extra
B globals
B ocaml
B parsing_c
B parsing_cocci
B popl
B popl09
B python
This diff is collapsed.
# This file is part of Coccinelle, lincensed under the terms of the GPL v2.
# This file is part of Coccinelle, licensed under the terms of the GPL v2.
# See copyright.txt in the Coccinelle source code for more information.
# The Coccinelle source code can be obtained at http://coccinelle.lip6.fr
......@@ -20,6 +20,19 @@ ifeq ($(BUILD_OPT),yes)
@echo "skipped building $@ in optimizing mode: $< will be built instead."
endif
define without_mli
ifeq ($(wildcard $(SOURCE).mli),)
ifeq ($(BUILD_OPT),yes)
$(SOURCE).cmo: $(SOURCE).cmx
$(SOURCE).cmi: $(SOURCE).cmx
else
$(SOURCE).cmi: $(SOURCE).cmo
endif
endif
endef
$(foreach SOURCE,$(SOURCES),$(eval $(without_mli)))
$(foreach SOURCE,$(SRC),$(eval $(without_mli)))
# If this variable is set, then 'make distclean' should not remove certain
# generated files like the generated parsers, and documentation.
......
......@@ -101,7 +101,7 @@ MANDIR=${mandir}
# Where to install the lib
LIBDIR=@LIBDIR@
BASH_COMPLETION_DIR=${sysconfdir}/bash_completion.d
BASH_COMPLETION_DIR=@BASH_COMPLETION_DIR@
# selected libraries
FEATURE_menhirLib=@FEATURE_menhirLib@
......@@ -118,6 +118,7 @@ PARMAPDIR=@PATH_parmap@
PYMLDIR=@PATH_pyml@
MENHIRDIR=@PATH_menhirLib@
DYNLINKDIR=@PATH_dynlink@
BYTESDIR=@PATH_bytes@
# selected ocaml modules
PYCOCCI_FILE=@PYCOCCI_FILE@
......
# This file is part of Coccinelle, lincensed under the terms of the GPL v2.
# This file is part of Coccinelle, licensed under the terms of the GPL v2.
# See copyright.txt in the Coccinelle source code for more information.
# The Coccinelle source code can be obtained at http://coccinelle.lip6.fr
......
.PHONY: library
library:
$(MAKE) -C .. $(LIBRARY)
\ No newline at end of file
......@@ -36,10 +36,10 @@ OPTFLAGS_pyml = $(CFLAGS_pyml:%=-ccopt %) -cclib -lpyml_stubs
# pcre library
# Note: see the comment of the pycaml library about the double appearance of the stubs library.
LOCAL_pcre = $(PCREDIR)/pcre.cma
LOCALOPT_pcre = $(PCREDIR)/pcre.cmxa
GLOBAL_pcre = $(PCREDIR)/pcre.cma
GLOBALOPT_pcre = $(PCREDIR)/pcre.cmxa
LOCAL_pcre = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre.cma
LOCALOPT_pcre = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre.cmxa
GLOBAL_pcre = $(BYTESDIR:=/bytes.cma) $(PCREDIR)/pcre.cma
GLOBALOPT_pcre = $(BYTESDIR:=/bytes.cmxa) $(PCREDIR)/pcre.cmxa
FLAGS_pcre = \
$(PCRE_LIBS:%=-ccopt %) -cclib -L$(PCREDIR) -dllib -lpcre_stubs \
-cclib -lpcre_stubs
......@@ -63,7 +63,6 @@ FLAGS_type_conv =
OPTFLAGS_type_conv =
# parmap library
PARMAPDIR = bundles/parmap/parmap-1.0-rc7/_build
LOCAL_parmap = $(PARMAPDIR)/parmap.cma
LOCALOPT_parmap = $(PARMAPDIR)/parmap.cmxa
GLOBAL_parmap = $(PARMAPDIR)/parmap.cma
......
LINK_BYTECODE :=
LINK_NATIVE :=
define find_package
$(package)_PATH := $$(shell ocamlfind query $(package) 2>/dev/null)
BYTECODE_MODULE := \
$$(wildcard $$(addsuffix /$(package).cma,$$($(package)_PATH)))
LINK_BYTECODE += \
$$(patsubst %,$$(patsubst %,-I % $(package).cma,$$($(package)_PATH)), \
$$(BYTECODE_MODULE))
NATIVE_MODULE := \
$$(wildcard $$(addsuffix /$(package).cmxa,$$($(package)_PATH)))
LINK_NATIVE += \
$$(patsubst %,$$(patsubst %,-I % $(package).cmxa,$$($(package)_PATH)), \
$$(NATIVE_MODULE))
endef
ifneq ($(OCAMLFIND),)
$(foreach package,result seq uchar,$(eval $(find_package)))
endif
# This file is part of Coccinelle, lincensed under the terms of the GPL v2.
# This file is part of Coccinelle, licensed under the terms of the GPL v2.
# See copyright.txt in the Coccinelle source code for more information.
# The Coccinelle source code can be obtained at http://coccinelle.lip6.fr
......
#!/bin/sh
#if [ "$1" = "--ignore_localversion" ]; then
# export MAKE_COCCI_RELEASE="y"
#else
# unset MAKE_COCCI_RELEASE
#fi
if [ "$1" = "--ignore_localversion" ]; then
export MAKE_COCCI_RELEASE="y"
else
unset MAKE_COCCI_RELEASE
fi
aclocal -I setup
autoconf -Wall
......@@ -16,12 +16,106 @@
- New scripting languages
- more than one SP on the command line
- interpret #if, as is done for #ifdef
- restored support for with-python in configure and support for --python option
in the command line to use a specific python interpreter
** Bugfix:
- Add more information in documentation, man pages and wiki
- typedefs from C code should not be used before their point of inference
(saved_typedefs in cprogram_of_file)
* 1.0.7
** Language:
- Allow constraints on any metavariables. Constraints can be specified
by comprehension (= { ... } or != { ... }, with each item referring
to a constant identifier or an inherited meta-variable, and
curly-brackets can be omitted for a single item), regular expression
(=~ "..." or !~ "..."), integer comparison (<=, <, >=, >) or scripts
(:script:...). Constraints can be used in conjunctions (&&),
disjunctions (||) and can be negated (!) and parenthesed.
Sub-expression constraints (<=) are still dealt separately and can
only be used individually or in conjunction with other constraints
(not under a disjunction or a negation). See tests/constraints.cocci
and tests/type_constraints.cocci
- Allow script finalizers for parallel computation. See
tests/countcalls.cocci and tests/countcalls_python.cocci
- Allow disjunctions on a wider range of syntactic constructions (function
definitions, variable declarations, ...). See tests/disj.cocci.
- Finalizers now occur before iteration loop and can register new
iterations.
- Multiple initializers and finalizers are allowed for the same language.
- Support function pointer types in casts.
- Allow something identified as a MacroDecl as a structure field.
- Conjunctions, ie ( & ), for declarations.
- Optional bitfield annotation on expression meta-variables. Requested by
Kumar Gala. See tests/bitfield_matching.cocci
- Bit-field matching, see tests/bitfield.cocci
- Anonymous field matching, see tests/anonfield.cocci
- current_element position information in position structure (ocaml &
python)
- matching and transformation of a single attribute after a variable name
in a variable declaration.
- add conjunctions on types.
- make addition of __attribute__((...)) on function definitions work
- add typeof to the semantic patch language
- require "name" when declaring attribute names.
- Support some changes on function pointer typedefs.
- allow a coccinelle ocaml script to detect whether parallelism is used,
via Flag.parmap_core (None for no pararallelism, and Some x for x cores)
- Make it possible to match or add an empty struct type declaration.
Suggestion of Michele Martone.
- --backup-suffix replaced by --suffix and made applicable to --out-place
** Features:
- Better error reporting for unparsable terms when using make_expr etc in
script code. Problem reported by Markus Elfring.
- --ignore command line argument to specify a prefix of the names of files
that should be ignored.
- added --max-width to adjust the line width for generated code. Requested
by Kumar Gala.
- forall and exists for quantifying over the success of matching depends on
constraints.
- --verbose-includes option to show what files are actually included
- allow casts to unknown typedefs on more kinds of constants (reported by
Yann Droneaud)
- Pick up header files that have the same name as the desired one if they
are unique in the provided include paths.
- Caching of parsed header files, --no-include-cache to disable.
- --force-kr and --prevent-kr options to control whether K&R parsing is
considered.
- Generalization of script constraints to allow reference to metavariables
defined in the same rule, only when the constrained metavariable always
occurs in rule_elems that also mention any othe local metavariables
mentioned in the script constraint. Referenced local variables must be
declared before the constrained one.
- Allow more variety in #pragmas
- Add macro names to Coccilib.current_element
- Get rid of code that depends on unbound virtual rules
- Bash-completion scripts are now installed in share/bash-completion/completions
(overridable with the new with-bash-completion option,
reported by Himanshu Jha)
- Allow using -o when only the main file changes, even if headers have been
matched.
- Preserve spacing for comments in statement and declaration metavariables,
when they are used in + code.
** Bugfix:
- Improved detection of metavariables in strings. Problem reported by
Wolfram Sang.
- Don't require all metavars in type exp meta constraint to be bound,
unless only one type is specified. Problem reported by Michael Stefaniuc.
- Finalization scripts are executed even in case there is no other script rules.
- spatch should find standard.iso and Python modules even if COCCINELLE_HOME
and PYTHONPATH are not set (either in the directory where the executable is
if it contains standard.iso, or in ../lib/coccinelle relatively to where the
executable is).
- Improve SmPL parsing of added __attribute__. Problem repported by
Eduardo Habkost.
- In python scripts, virtuals should not overwrite locals with the same
name. Problem reported by Bhumika Goyal.
- Identify typedefs in type metavariable constraints, problem identified by
Michele Martone.
- #ifdefs and cpp directives should not be able to be bound to MetaField
metavariables. Problem found using an example contributed by Michele
Martone.
* 1.0.6
** Language:
- Allow \ in #define in semantic patch rules, to allow body with multiple
......
This diff is collapsed.
(*
* This file is part of Coccinelle, lincensed under the terms of the GPL v2.
* This file is part of Coccinelle, licensed under the terms of the GPL v2.
* See copyright.txt in the Coccinelle source code for more information.
* The Coccinelle source code can be obtained at http://coccinelle.lip6.fr
*)
......@@ -24,12 +24,13 @@ type constant_info =
(Str.regexp * Str.regexp list * string list)
option (*coccigrep/gitgrep tokens*) *
Get_constants2.combine option
type merge_vars = string array list * string array list
val union_merge_vars : merge_vars -> merge_vars -> merge_vars
val pre_engine : (filename * filename) -> cocci_info * constant_info
val worth_trying : filename list -> constant_info -> bool
val full_engine :
cocci_info -> filename list -> (filename * filename option) list
val post_engine : cocci_info -> unit
val has_finalize : cocci_info -> bool
cocci_info -> filename list -> (filename * filename option) list * merge_vars
val post_engine : cocci_info -> merge_vars -> unit
(* because of the #include "toto.c" and also because we may associate the
* same C file to multiple drivers because they share code, we can
......@@ -44,6 +45,7 @@ val check_duplicate_modif :
val sp_of_file :
filename (* coccifile *) -> filename option (* isofile *) ->
Ast_cocci.metavar list list * Ast_cocci.rule list *
Ast_cocci.rule list (*scripts to compile*) *
Ast_cocci.meta_name list list list *
(Ast_cocci.meta_name list * Ast_cocci.meta_name list) list list * (*pos*)
(Ast_cocci.meta_name list list list (*used after list*) *
......@@ -52,6 +54,7 @@ val sp_of_file :
(*fresh used after list seeds*)
Ast_cocci.meta_name list list list) *
Ast_cocci.meta_name list list list * constant_info *
bool (* format information needed for strings? *)
bool (* format information needed for strings? *) *
bool (* contains modif in any rule *)
val normalize_path : string -> string
This diff is collapsed.
val coccinelle: string -> unit
##############################################################################
# Variables
##############################################################################
LIBRARY=commons
# The main library
ifneq ($(MAKECMDGOALS),distclean)
include ../Makefile.config
-include ../Makefile.local
endif
TARGET=commons
# note: if you add a file (a .mli or .ml), dont forget to redo a 'make depend'
MYSRC= commands.ml \
common.ml \
ograph_simple.ml ograph_extended.ml
MLI_FILES=\
common.mli \
objet.mli \
ocollection.mli \
ograph_extended.mli \
ograph_simple.mli
# src from other authors, got from the web or caml hump
SRC=ocamlextra/dumper.ml
SRC+=$(MYSRC)
SYSLIBS=str.cma bigarray.cma unix.cma
INCLUDEDIRS=ocamlextra
SUBDIRS=ocamlextra
#-----------------------------------------------------------------------------
# Other common (thin wrapper) libraries
#-----------------------------------------------------------------------------
#format: XXXSRC, XXXINCLUDE, XXXSYSLIBS
#lablgtk (ocamlgtk)
MYGUISRC=gui.ml
GUIINCLUDES=-I +lablgtk2 -I +lablgtksourceview -I ../ocamlgtk/src
GUISYSLIBS=lablgtk.cma lablgtksourceview.cma
#pycaml (ocamlpython)
MYPYSRC=python.ml
PYINCLUDES=-I ../ocamlpython -I ../../ocamlpython
PYSYSLIBS=python.cma
#ocamlmpi
MYMPISRC=distribution.ml
MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi
MPISYSLIBS=mpi.cma
#binprot
MYBINSRC=bin_common.ml
BININCLUDES=-I ../ocamltarzan/lib-binprot -I ../../ocamltarzan/lib-binprot
#-----------------------------------------------------------------------------
# Other stuff
#-----------------------------------------------------------------------------
##############################################################################
# Generic variables
##############################################################################
INCLUDES=$(INCLUDEDIRS:%=-I %) $(INCLUDESEXTRA)
##############################################################################
# Generic ocaml variables
##############################################################################
# This flag can also be used in subdirectories so don't change its name here.
# For profiling use: -p -inline 0
OCAMLCFLAGS ?= -g
OPTFLAGS ?= -g
# The OPTBIN variable is here to allow to use ocamlc.opt instead of
# ocaml, when it is available, which speeds up compilation. So
# if you want the fast version of the ocaml chain tools, set this var
# or setenv it to ".opt" in your startup script.
OPTBIN ?= #.opt
# The OCaml tools.
OCAMLC_CMD=$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES)
OCAMLOPT_CMD=$(OCAMLOPT) $(OPTFLAGS) $(INCLUDES)
OCAMLDEP_CMD=$(OCAMLDEP) $(INCLUDES)
OCAMLMKTOP_CMD=$(OCAMLMKTOP) -g -custom $(INCLUDES)
##############################################################################
# Top rules
##############################################################################
LIB=$(TARGET).cma
OPTLIB=$(LIB:.cma=.cmxa)
OBJS = $(SRC:.ml=.cmo)
OPTOBJS = $(SRC:.ml=.cmx)
all: $(LIB)
all.opt:
@$(MAKE) $(OPTLIB) BUILD_OPT=yes
opt: all.opt
top: $(TARGET).top
$(LIB): $(OBJS)
$(OCAMLC_CMD) -a -o $@ $^
$(OPTLIB): $(OPTOBJS)
$(OCAMLOPT_CMD) -a -o $@ $^
$(TARGET).top: $(OBJS)
$(OCAMLMKTOP_CMD) -o $@ $(SYSLIBS) $^
clean::
rm -f $(TARGET).top
##############################################################################
# Other commons libs target
##############################################################################
all_libs: bdb gui mpi backtrace
#-----------------------------------------------------------------------------
gui:
$(MAKE) INCLUDESEXTRA="$(GUIINCLUDES)" commons_gui.cma
gui.opt:
$(MAKE) INCLUDESEXTRA="$(GUIINCLUDES)" commons_gui.cmxa
commons_gui.cma: $(MYGUISRC:.ml=.cmo)
$(OCAMLC_CMD) -a -o $@ $^
commons_gui.cmxa: $(MYGUISRC:.ml=.cmx)
$(OCAMLOPT_CMD) -a -o $@ $^
#-----------------------------------------------------------------------------
mpi:
$(MAKE) INCLUDESEXTRA="$(MPIINCLUDES)" commons_mpi.cma
mpi.opt:
$(MAKE) INCLUDESEXTRA="$(MPIINCLUDES)" commons_mpi.cmxa
commons_mpi.cma: $(MYMPISRC:.ml=.cmo)
$(OCAMLC_CMD) -a -o $@ $^
commons_mpi.cmxa: $(MYMPISRC:.ml=.cmx)
$(OCAMLOPT_CMD) -a -o $@ $^
#alias
distribution: mpi
distribution.opt: mpi.opt
#-----------------------------------------------------------------------------
python:
$(MAKE) INCLUDESEXTRA="$(PYINCLUDES)" commons_python.cma
python.opt:
$(MAKE) INCLUDESEXTRA="$(PYINCLUDES)" commons_python.cmxa
commons_python.cma: $(MYPYSRC:.ml=.cmo)
$(OCAMLC_CMD) -a -o $@ $^
commons_python.cmxa: $(MYPYSRC:.ml=.cmx)
$(OCAMLOPT_CMD) -a -o $@ $^
#-----------------------------------------------------------------------------
binprot:
$(MAKE) INCLUDESEXTRA="$(BININCLUDES)" commons_bin.cma
binprot.opt:
$(MAKE) INCLUDESEXTRA="$(BININCLUDES)" commons_bin.cmxa
commons_bin.cma: $(MYBINSRC:.ml=.cmo)
$(OCAMLC_CMD) -a -o $@ $^
commons_bin.cmxa: $(MYBINSRC:.ml=.cmx)
$(OCAMLOPT_CMD) -a -o $@ $^
##############################################################################
# Developer rules
##############################################################################
tags:
otags -no-mli-tags -r .
clean::
rm -f gmon.out
forprofiling:
$(MAKE) OPTFLAGS="-p -inline 0 " opt
dependencygraph:
ocamldep *.mli *.ml > /tmp/dependfull.depend
ocamldot -fullgraph /tmp/dependfull.depend > /tmp/dependfull.dot
dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
dependencygraph2:
find -name "*.ml" |grep -v "scripts" | xargs ocamldep -I commons -I globals -I ctl -I parsing_cocci -I parsing_c -I engine -I popl -I extra > /tmp/dependfull.depend
ocamldot -fullgraph /tmp/dependfull.depend > /tmp/dependfull.dot
dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
##############################################################################
# Generic rules
##############################################################################
.SUFFIXES:
.SUFFIXES: .ml .mli .cmo .cmi .cmx
.ml.cmo:
$(OCAMLC_CMD) -c $<
.mli.cmi:
$(OCAMLC_CMD) -c $<
.ml.cmx:
$(OCAMLOPT_CMD) -c $<
clean::
rm -f *.cm[iox] *.o *.a *.cma *.cmxa *.annot
rm -f *~ .*~ #*#
clean::
for i in $(SUBDIRS); do (cd $$i; \
rm -f *.cm[iox] *.o *.a *.cma *.cmxa *.annot *~ .*~ ; \
cd ..; ) \
done
rm -f .depend
distclean: clean
rm -f commands.ml
.PHONY: depend
.depend depend:
$(OCAMLDEP_CMD) $(MLI_FILES) $(MYSRC) > .depend
for i in $(SUBDIRS); do $(OCAMLDEP_CMD) $$i/*.ml $$i/*.mli >> .depend; done
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),distclean)
-include .depend
endif
endif
include ../Makefile.common
include ../Makefile.library
val ocamlfind_cmd : string
val ocamlc_cmd : string
val ocamlopt_cmd : string
val ocamldep_cmd : string
......@@ -186,7 +186,7 @@ let matched7 = fun s -> (matched 1 s, matched 2 s, matched 3 s, matched 4 s, mat
let (with_open_stringbuf: (((string -> unit) * Buffer.t) -> unit) -> string) =
fun f ->
let buf = Buffer.create 1000 in
let buf = Buffer.create 100 in
let pr s = Buffer.add_string buf (s ^ "\n") in
f (pr, buf);
Buffer.contents buf
......@@ -573,7 +573,7 @@ let check_profile category =
| PNONE -> false
| PSOME l -> List.mem category l
let _profile_table = ref (Hashtbl.create 100)
let _profile_table = ref (Hashtbl.create 101)
let adjust_profile_entry category difftime =
let (xtime, xcount) =
......@@ -2200,15 +2200,6 @@ let (<!!>) s (i,j) =
let (<!>) s i = String.get s i
(* pixel *)
let rec split_on_char c s =
try
let sp = String.index s c in
String.sub s 0 sp ::
split_on_char c (String.sub s (sp+1) (String.length s - sp - 1))
with Not_found -> [s]
let lowercase = String.lowercase
let quote s = "\"" ^ s ^ "\""
......@@ -2454,6 +2445,42 @@ let filename_without_leading_path prj_path s =
failwith
(spf "cant find filename_without_project_path: %s %s" prj_path s)
let rec join_path dir path =
match path with
[] -> assert false
| hd :: tl ->
if hd = Filename.current_dir_name then
join_path dir tl
else if hd = Filename.parent_dir_name then
join_path (Filename.dirname dir) tl
else
List.fold_left Filename.concat dir path
let rec path_of_filename accu filename =
let accu = Filename.basename filename :: accu in
let dirname = Filename.dirname filename in
if dirname = filename then
accu
else
path_of_filename accu dirname
let path_of_filename filename = path_of_filename [] filename
let join_filename dir filename =
if Filename.is_relative filename then
join_path dir (path_of_filename filename)
else
filename
let rec resolve_symlink filename =
match
try Some (Unix.readlink filename)
with _ -> None
with
Some realpath ->
let dirname = Filename.dirname filename in
resolve_symlink (join_filename dirname realpath)
| None -> filename
(*****************************************************************************)
(* i18n *)
......@@ -3471,10 +3498,14 @@ let remove_file path =
let _temp_files_created = ref ([] : filename list)
let temp_files = ref "/tmp"
(* ex: new_temp_file "cocci" ".c" will give "/tmp/cocci-3252-434465.c" *)
let new_temp_file prefix suffix =
let processid = string_of_int (Unix.getpid ()) in
let tmp_file = Filename.temp_file (prefix ^ "-" ^ processid ^ "-") suffix in
let tmp_file =
Filename.temp_file ~temp_dir:(!temp_files)
(prefix ^ "-" ^ processid ^ "-") suffix in
push2 tmp_file _temp_files_created;
tmp_file
......@@ -4660,6 +4691,24 @@ let hash_of_list xs =
h
end
let hashadd tbl k v =
let cell =
try Hashtbl.find tbl k
with Not_found ->
let cell = ref [] in
Hashtbl.add tbl k cell;
cell in
if not (List.mem v !cell) then cell := v :: !cell
let hashinc tbl k v =
let cell =
try Hashtbl.find tbl k
with Not_found ->
let cell = ref 0 in
Hashtbl.add tbl k cell;
cell in
cell := v + !cell
let _ =
let h = Hashtbl.create 101 in
Hashtbl.add h "toto" 1;
......@@ -4727,8 +4776,7 @@ let group_assoc_bykey_eff2 xs =
keys +> List.map (fun k -> k, Hashtbl.find_all h k)
let group_assoc_bykey_eff xs =
profile_code2 "Common.group_assoc_bykey_eff" (fun () ->
group_assoc_bykey_eff2 xs)
group_assoc_bykey_eff2 xs
let test_group_assoc () =
......@@ -5299,44 +5347,6 @@ let (diff2: (int -> int -> diff -> unit) -> (string * string) -> unit) =
)
(*****************************************************************************)
(* Parsers (aop-colcombet) *)
(*****************************************************************************)
let parserCommon lexbuf parserer lexer =
try
let result = parserer lexer lexbuf in
result
with Parsing.Parse_error ->
print_string "buf: "; print_string lexbuf.Lexing.lex_buffer;
print_string "\n";
print_string "current: "; print_int lexbuf.Lexing.lex_curr_pos;
print_string "\n";
raise Parsing.Parse_error
(* marche pas ca neuneu *)
(*
let getDoubleParser parserer lexer string =
let lexbuf1 = Lexing.from_string string in
let chan = open_in string in
let lexbuf2 = Lexing.from_channel chan in
(parserCommon lexbuf1 parserer lexer , parserCommon lexbuf2 parserer lexer )
*)
let getDoubleParser parserer lexer =
(
(function string ->
let lexbuf1 = Lexing.from_string string in
parserCommon lexbuf1 parserer lexer
),
(function string ->
let chan = open_in string in
let lexbuf2 = Lexing.from_channel chan in
parserCommon lexbuf2 parserer lexer
))
(*****************************************************************************)
(* parser combinators *)
(*****************************************************************************)
......@@ -5972,25 +5982,16 @@ let with_pr2_to_string f =
(* julia: convert something printed using format to print into a string *)
let format_to_string f =
let (nm,o) = Filename.open_temp_file "format_to_s" ".out" in
Format.set_formatter_out_channel o;
let acc = ref [] in
let (pr,flush) = Format.get_formatter_output_functions() in
Format.set_formatter_output_functions
(fun s p n -> acc := String.sub s p n :: !acc)
(fun _ -> ());
let _ = f() in
Format.print_newline();
Format.print_flush();
Format.set_formatter_out_channel stdout;
close_out o;
let i = open_in nm in
let lines = ref [] in
let rec loop _ =
let cur = input_line i in
lines := cur :: !lines;
loop() in
(try loop() with End_of_file -> ());
close_in i;
command2 ("rm -f " ^ nm);
String.concat "\n" (List.rev !lines)
Format.set_formatter_output_functions pr flush;
String.concat "" (List.rev !acc)
(*****************************************************************************)
(* Misc/test *)
......@@ -6033,3 +6034,57 @@ let typing_sux_test () =
(* let _ = test (new osetb (Setb.empty)) *)
module StringSet = Set.Make (String)
(* --------------------------------------------------------------------- *)
type 'a dll = DElem of 'a dll option ref * 'a * 'a dll option ref
let get_dll cell =
match !cell with
None -> failwith "bad cell"
| Some x -> x
let add_first_dll hd x =
let (DElem(bprev,_,bnext)) as bef = hd in
let (DElem(aprev,_,anext)) as aft = get_dll bnext in
let self = DElem(ref (Some bef),x,ref (Some aft)) in
bnext := Some self; aprev := Some self;
self
let remove_last_dll hd =
let (DElem(aprev,_,anext)) as aft = hd in
let (DElem(dprev,_,dnext)) as drop = get_dll aprev in
let (DElem(bprev,_,bnext)) as bef = get_dll dprev in
aprev := Some bef; bnext := Some aft;
drop
let create_bounded_cache n hval =
let tbl = Hashtbl.create 101 in
let prev = ref None in
let next = ref None in
let lst = DElem (prev,hval,next) in
prev := Some lst; next := Some lst;
(n,ref 0,tbl,lst)
let find_bounded_cache (n,cur,tbl,lst) x =
try
let DElem(prev,hval,next) = Hashtbl.find tbl x in
let _ = remove_last_dll (get_dll next) in
let _ = add_first_dll lst hval in
profile_code ("ok"^(string_of_int n)) (fun _ -> snd hval)
with x ->
(profile_code ("miss"^(string_of_int n)) (fun _ -> ());
raise x)
let extend_bounded_cache (n,cur,tbl,lst) x v =
cur := !cur + 1;
(if !cur > n
then
for i = 1 to (n/2) do
let DElem(prev,hval,next) = remove_last_dll lst in
Hashtbl.remove tbl (fst hval);
cur := !cur - 1
done);
let elem = add_first_dll lst (x,v) in
profile_code ("add"^(string_of_int n)) (fun _ -> ());
Hashtbl.add tbl x elem
......@@ -792,10 +792,6 @@ val ( <!> ) : string -> int -> char
val take_string: int -> string -> string
val take_string_safe: int -> string -> string
val split_on_char : char -> string -> string list
val lowercase : string -> string
val quote : string -> string
val is_blank_string : string -> bool
......@@ -890,6 +886,15 @@ val is_absolute: filename -> bool
val filename_without_leading_path : string -> filename -> filename
val join_filename : filename -> filename -> filename
(** like Filename.concat, but simplify . and .. that occur in the second
argument *)
val resolve_symlink : filename -> filename
(** if the argument is a symbolic link, follow it recursively and
return the target. Otherwise, return the argument unchanged.
Symbolic links on the parent directories are not resolved. *)
(*****************************************************************************)
(* i18n *)
(*****************************************************************************)
......@@ -1106,6 +1111,7 @@ val remove_file : string -> unit
*)
val _temp_files_created : string list ref
(* see flag: val save_tmp_files : bool ref *)
val temp_files : string ref
val new_temp_file : string (* prefix *) -> string (* suffix *) -> filename
val erase_temp_files : unit -> unit
val erase_this_temp_file : filename -> unit
......@@ -1498,71 +1504,11 @@ val sortgen_by_key_highfirst: ('a,'b) assoc -> ('a * 'b) list
(* Assoc, specialized. *)
(*****************************************************************************)
module IntMap :
sig
type key = int
type +'a t
val empty : 'a t
val is_empty : 'a t -> bool
val mem : key -> 'a t -> bool
val add : key -> 'a -> 'a t -> 'a t
val singleton : key -> 'a -> 'a t
val find : key -> 'a t -> 'a
val remove : key -> 'a t -> 'a t
val merge : (key -> 'a option -> 'b option -> 'c option) ->
'a t -> 'b t -> 'c t
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val for_all : (key -> 'a -> bool) -> 'a t -> bool
val exists : (key -> 'a -> bool) -> 'a t -> bool
val filter : (key -> 'a -> bool) -> 'a t -> 'a t
val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
val cardinal : 'a t -> int
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val max_binding : 'a t -> key * 'a
val choose : 'a t -> key * 'a
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
end
module IntMap : Map.S with type key = int
val intmap_to_list : 'a IntMap.t -> (IntMap.key * 'a) list
val intmap_string_of_t : 'a -> 'b -> string
module IntIntMap :
sig
type key = int * int
type +'a t
val empty : 'a t
val is_empty : 'a t -> bool
val mem : key -> 'a t -> bool
val add : key -> 'a -> 'a t -> 'a t
val singleton : key -> 'a -> 'a t
val find : key -> 'a t -> 'a
val remove : key -> 'a t -> 'a t
val merge : (key -> 'a option -> 'b option -> 'c option) ->
'a t -> 'b t -> 'c t
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val for_all : (key -> 'a -> bool) -> 'a t -> bool
val exists : (key -> 'a -> bool) -> 'a t -> bool
val filter : (key -> 'a -> bool) -> 'a t -> 'a t
val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
val cardinal : 'a t -> int
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val max_binding : 'a t -> key * 'a
val choose : 'a t -> key * 'a
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
end
module IntIntMap : Map.S with type key = int * int
val intintmap_to_list : 'a IntIntMap.t -> (IntIntMap.key * 'a) list
val intintmap_string_of_t : 'a -> 'b -> string
......@@ -1599,6 +1545,9 @@ val hash_to_list : ('a, 'b) Hashtbl.t -> ('a * 'b) list
val hash_to_list_unsorted : ('a, 'b) Hashtbl.t -> ('a * 'b) list
val hash_of_list : ('a * 'b) list -> ('a, 'b) Hashtbl.t
val hashadd : ('a, 'b list ref) Hashtbl.t -> 'a -> 'b -> unit
val hashinc : ('a, int ref) Hashtbl.t -> 'a -> int -> unit
val hkeys : ('a, 'b) Hashtbl.t -> 'a list
......@@ -1848,14 +1797,6 @@ type diff = Match | BnotinA | AnotinB
val diff : (int -> int -> diff -> unit) -> string list * string list -> unit
val diff2 : (int -> int -> diff -> unit) -> string * string -> unit
(*****************************************************************************)
(* Parsers (aop-colcombet) *)
(*****************************************************************************)
val parserCommon : Lexing.lexbuf -> ('a -> Lexing.lexbuf -> 'b) -> 'a -> 'b
val getDoubleParser :
('a -> Lexing.lexbuf -> 'b) -> 'a -> (string -> 'b) * (string -> 'b)
(*****************************************************************************)
(* Parsers (cocci) *)
(*****************************************************************************)
......@@ -1981,3 +1922,21 @@ class ['a] olist :
val typing_sux_test : unit -> unit
module StringSet: Set.S with type elt = string
(*****************************************************************************)
(* cache *)
(*****************************************************************************)
type 'a dll = DElem of 'a dll option ref * 'a * 'a dll option ref
val create_bounded_cache :
int -> ('a * 'b) ->
(int * int ref * ('a,('a * 'b) dll) Hashtbl.t * ('a * 'b) dll)
val find_bounded_cache :
(int * int ref * ('a,('a * 'b) dll) Hashtbl.t * ('a * 'b) dll) ->
'a -> 'b
val extend_bounded_cache :
(int * int ref * ('a,('a * 'b) dll) Hashtbl.t * ('a * 'b) dll) ->
'a -> 'b -> unit