summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/tools
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/tools')
-rw-r--r--ocaml-binary-annot/tools/.cvsignore25
-rw-r--r--ocaml-binary-annot/tools/.depend62
-rw-r--r--ocaml-binary-annot/tools/Characters16
-rw-r--r--ocaml-binary-annot/tools/DoMake61
-rw-r--r--ocaml-binary-annot/tools/MakeDepend17
-rw-r--r--ocaml-binary-annot/tools/Makefile21
-rw-r--r--ocaml-binary-annot/tools/Makefile.nt23
-rw-r--r--ocaml-binary-annot/tools/Makefile.shared280
-rw-r--r--ocaml-binary-annot/tools/OCamlc-custom10
-rw-r--r--ocaml-binary-annot/tools/Time10
-rw-r--r--ocaml-binary-annot/tools/addlabels.ml453
-rw-r--r--ocaml-binary-annot/tools/checkstack.c43
-rw-r--r--ocaml-binary-annot/tools/cleanup-header13
-rw-r--r--ocaml-binary-annot/tools/cvt_emit.mll84
-rw-r--r--ocaml-binary-annot/tools/depend.ml306
-rw-r--r--ocaml-binary-annot/tools/depend.mli23
-rw-r--r--ocaml-binary-annot/tools/dumpobj.ml560
-rw-r--r--ocaml-binary-annot/tools/lexer299.mll460
-rw-r--r--ocaml-binary-annot/tools/lexer301.mll461
-rw-r--r--ocaml-binary-annot/tools/magic11
-rw-r--r--ocaml-binary-annot/tools/make-opcodes2
-rwxr-xr-xocaml-binary-annot/tools/make-package-macosx129
-rw-r--r--ocaml-binary-annot/tools/objinfo.ml269
-rw-r--r--ocaml-binary-annot/tools/objinfo_helper.c92
-rwxr-xr-xocaml-binary-annot/tools/ocaml-objcopy-macosx54
-rw-r--r--ocaml-binary-annot/tools/ocaml299to3.ml139
-rw-r--r--ocaml-binary-annot/tools/ocamlcp.ml137
-rw-r--r--ocaml-binary-annot/tools/ocamldep.ml310
-rw-r--r--ocaml-binary-annot/tools/ocamlmklib.mlp281
-rw-r--r--ocaml-binary-annot/tools/ocamlmktop.ml17
-rw-r--r--ocaml-binary-annot/tools/ocamlmktop.tpl16
-rw-r--r--ocaml-binary-annot/tools/ocamlprof.ml503
-rwxr-xr-xocaml-binary-annot/tools/ocamlsize49
-rw-r--r--ocaml-binary-annot/tools/primreq.ml90
-rw-r--r--ocaml-binary-annot/tools/profiling.ml56
-rw-r--r--ocaml-binary-annot/tools/profiling.mli20
-rw-r--r--ocaml-binary-annot/tools/scrapelabels.ml289
37 files changed, 5392 insertions, 0 deletions
diff --git a/ocaml-binary-annot/tools/.cvsignore b/ocaml-binary-annot/tools/.cvsignore
new file mode 100644
index 0000000000..cf3c69515d
--- /dev/null
+++ b/ocaml-binary-annot/tools/.cvsignore
@@ -0,0 +1,25 @@
+ocamldep
+ocamldep.opt
+ocamldep.bak
+ocamlprof
+opnames.ml
+dumpobj
+dumpapprox
+objinfo
+cvt_emit
+cvt_emit.bak
+cvt_emit.ml
+ocamlcp
+ocamlmktop
+primreq
+ocamldumpobj
+keywords
+lexer299.ml
+ocaml299to3
+ocamlmklib
+ocamlmklib.ml
+lexer301.ml
+scrapelabels
+addlabels
+myocamlbuild_config.ml
+objinfo_helper
diff --git a/ocaml-binary-annot/tools/.depend b/ocaml-binary-annot/tools/.depend
new file mode 100644
index 0000000000..36c177ed43
--- /dev/null
+++ b/ocaml-binary-annot/tools/.depend
@@ -0,0 +1,62 @@
+depend.cmi: ../parsing/parsetree.cmi
+profiling.cmi:
+addlabels.cmo: ../parsing/parsetree.cmi ../parsing/parse.cmi \
+ ../parsing/longident.cmi ../parsing/location.cmi ../parsing/asttypes.cmi
+addlabels.cmx: ../parsing/parsetree.cmi ../parsing/parse.cmx \
+ ../parsing/longident.cmx ../parsing/location.cmx ../parsing/asttypes.cmi
+cvt_emit.cmo:
+cvt_emit.cmx:
+depend.cmo: ../parsing/parsetree.cmi ../parsing/longident.cmi \
+ ../parsing/location.cmi depend.cmi
+depend.cmx: ../parsing/parsetree.cmi ../parsing/longident.cmx \
+ ../parsing/location.cmx depend.cmi
+dumpobj.cmo: ../utils/tbl.cmi opnames.cmo ../bytecomp/opcodes.cmo \
+ ../parsing/location.cmi ../bytecomp/lambda.cmi ../bytecomp/instruct.cmi \
+ ../typing/ident.cmi ../bytecomp/emitcode.cmi ../utils/config.cmi \
+ ../bytecomp/cmo_format.cmi ../bytecomp/bytesections.cmi \
+ ../parsing/asttypes.cmi
+dumpobj.cmx: ../utils/tbl.cmx opnames.cmx ../bytecomp/opcodes.cmx \
+ ../parsing/location.cmx ../bytecomp/lambda.cmx ../bytecomp/instruct.cmx \
+ ../typing/ident.cmx ../bytecomp/emitcode.cmx ../utils/config.cmx \
+ ../bytecomp/cmo_format.cmi ../bytecomp/bytesections.cmx \
+ ../parsing/asttypes.cmi
+myocamlbuild_config.cmo:
+myocamlbuild_config.cmx:
+objinfo.cmo: ../utils/misc.cmi ../utils/config.cmi ../asmcomp/cmx_format.cmi \
+ ../bytecomp/cmo_format.cmi ../asmcomp/clambda.cmi \
+ ../bytecomp/bytesections.cmi
+objinfo.cmx: ../utils/misc.cmx ../utils/config.cmx ../asmcomp/cmx_format.cmi \
+ ../bytecomp/cmo_format.cmi ../asmcomp/clambda.cmx \
+ ../bytecomp/bytesections.cmx
+ocaml299to3.cmo:
+ocaml299to3.cmx:
+ocamlcp.cmo: ../driver/main_args.cmi
+ocamlcp.cmx: ../driver/main_args.cmx
+ocamldep.cmo: ../parsing/syntaxerr.cmi ../parsing/parsetree.cmi \
+ ../parsing/parse.cmi ../utils/misc.cmi ../parsing/longident.cmi \
+ ../parsing/location.cmi ../parsing/lexer.cmi depend.cmi \
+ ../utils/config.cmi ../utils/clflags.cmi
+ocamldep.cmx: ../parsing/syntaxerr.cmx ../parsing/parsetree.cmi \
+ ../parsing/parse.cmx ../utils/misc.cmx ../parsing/longident.cmx \
+ ../parsing/location.cmx ../parsing/lexer.cmx depend.cmx \
+ ../utils/config.cmx ../utils/clflags.cmx
+ocamlmklib.cmo: myocamlbuild_config.cmo
+ocamlmklib.cmx: myocamlbuild_config.cmx
+ocamlmktop.cmo: ../utils/ccomp.cmi
+ocamlmktop.cmx: ../utils/ccomp.cmx
+ocamlprof.cmo: ../utils/warnings.cmi ../parsing/syntaxerr.cmi \
+ ../parsing/parsetree.cmi ../parsing/parse.cmi ../utils/misc.cmi \
+ ../parsing/location.cmi ../parsing/lexer.cmi ../utils/config.cmi \
+ ../utils/clflags.cmi
+ocamlprof.cmx: ../utils/warnings.cmx ../parsing/syntaxerr.cmx \
+ ../parsing/parsetree.cmi ../parsing/parse.cmx ../utils/misc.cmx \
+ ../parsing/location.cmx ../parsing/lexer.cmx ../utils/config.cmx \
+ ../utils/clflags.cmx
+opnames.cmo:
+opnames.cmx:
+primreq.cmo: ../utils/config.cmi ../bytecomp/cmo_format.cmi
+primreq.cmx: ../utils/config.cmx ../bytecomp/cmo_format.cmi
+profiling.cmo: profiling.cmi
+profiling.cmx: profiling.cmi
+scrapelabels.cmo:
+scrapelabels.cmx:
diff --git a/ocaml-binary-annot/tools/Characters b/ocaml-binary-annot/tools/Characters
new file mode 100644
index 0000000000..fb8e6868ab
--- /dev/null
+++ b/ocaml-binary-annot/tools/Characters
@@ -0,0 +1,16 @@
+# Characters
+
+# $Id$
+
+# Usage:
+# Characters n1 to n2
+#
+# Select the characters in the given interval, counting from the first
+# character of the current line, in the active window.
+#
+# Typical use is an error message of the form:
+# File fff; Line lll; Characters yyy to zzz
+
+exit 1 if {#} ­ 3
+
+Find Ƥ!{1}:¤!`evaluate {3} - {1}` "{active}"
diff --git a/ocaml-binary-annot/tools/DoMake b/ocaml-binary-annot/tools/DoMake
new file mode 100644
index 0000000000..2fce340103
--- /dev/null
+++ b/ocaml-binary-annot/tools/DoMake
@@ -0,0 +1,61 @@
+# DoMake
+
+# $Id$
+
+# Execute the output of "Make -f Makefile.Mac -f Makefile.Mac.depend"
+# or "Make -f Makefile -f Makefile.depend" if "Makefile.Mac" does not exist
+# or "Make -f <file>" if the "-f" option is given.
+
+# usage: domake [-quiet] [-f <file>]É <make arguments>
+
+set echo 0
+
+set domake_quiet 0
+set domake_files ""
+
+loop
+ if "{1}" == "-quiet"
+ set domake_quiet 1
+ shift
+ else if "{1}" == "-f"
+ set domake_files "{domake_files} -f `quote "{2}"`"
+ shift 2
+ else
+ break
+ end
+end
+
+set tempfile "{TempFolder}temp-domake-`Date -n`"
+if "`exists "{tempfile}"`"
+ set i 0
+ loop
+ break if ! "`exists "{tempfile}.{i}"`"
+ evaluate i += 1
+ end
+ set tempfile "{tempfile}.{i}"
+end
+
+if "{domake_files}" == ""
+ if "`exists Makefile.Mac`" != ""
+ set domake_main "Makefile.Mac"
+ else
+ set domake_main "Makefile"
+ end
+
+ if "`exists "{domake_main}".depend`" != ""
+ set domake_files "-f {domake_main} -f {domake_main}.depend"
+ else
+ set domake_files "-f {domake_main}"
+ end
+end
+
+if {domake_quiet}
+ echo >"{tempfile}"
+else
+ echo 'set echo 1' >"{tempfile}"
+end
+make {domake_files} {"Parameters"} >>"{tempfile}"
+
+"{tempfile}"
+
+Delete -i "{tempfile}"
diff --git a/ocaml-binary-annot/tools/MakeDepend b/ocaml-binary-annot/tools/MakeDepend
new file mode 100644
index 0000000000..5693b27e8d
--- /dev/null
+++ b/ocaml-binary-annot/tools/MakeDepend
@@ -0,0 +1,17 @@
+# MakeDepend
+
+# $Id$
+
+
+# Usage: MakeDepend fileÉ
+
+# Generate the Make dependency rules for a set of C files.
+# The rules are printed on standard output.
+
+set echo 0
+set exit 0
+
+for i in {"parameters"}
+ mrc -c -w off -make dev:stdout "{i}" ³ dev:null ¶
+ | streamedit -e '/¶"(Å)¨0.c.o¶"/ replace // "¶""¨0".c.o¶" ¶""¨0".c.x¶""'
+end
diff --git a/ocaml-binary-annot/tools/Makefile b/ocaml-binary-annot/tools/Makefile
new file mode 100644
index 0000000000..bad14c7e50
--- /dev/null
+++ b/ocaml-binary-annot/tools/Makefile
@@ -0,0 +1,21 @@
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Xavier Leroy, projet Cristal, INRIA Rocquencourt #
+# #
+# Copyright 1999 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+include Makefile.shared
+
+# To make custom toplevels
+
+ocamlmktop: ocamlmktop.tpl ../config/Makefile
+ sed -e 's|%%BINDIR%%|$(BINDIR)|' ocamlmktop.tpl > ocamlmktop
+ chmod +x ocamlmktop
diff --git a/ocaml-binary-annot/tools/Makefile.nt b/ocaml-binary-annot/tools/Makefile.nt
new file mode 100644
index 0000000000..b90c0c4f66
--- /dev/null
+++ b/ocaml-binary-annot/tools/Makefile.nt
@@ -0,0 +1,23 @@
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Xavier Leroy, projet Cristal, INRIA Rocquencourt #
+# #
+# Copyright 1999 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+include Makefile.shared
+
+# To make custom toplevels
+
+OCAMLMKTOP=ocamlmktop.cmo
+OCAMLMKTOP_IMPORTS=misc.cmo config.cmo clflags.cmo ccomp.cmo
+
+ocamlmktop: $(OCAMLMKTOP)
+ $(CAMLC) $(LINKFLAGS) -o ocamlmktop $(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP)
diff --git a/ocaml-binary-annot/tools/Makefile.shared b/ocaml-binary-annot/tools/Makefile.shared
new file mode 100644
index 0000000000..12bf76f0d0
--- /dev/null
+++ b/ocaml-binary-annot/tools/Makefile.shared
@@ -0,0 +1,280 @@
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Xavier Leroy, projet Cristal, INRIA Rocquencourt #
+# #
+# Copyright 1999 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+include ../config/Makefile
+
+CAMLRUN=../boot/ocamlrun
+CAMLC=$(CAMLRUN) ../boot/ocamlc -strict-sequence -nostdlib -I ../boot
+CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib
+CAMLLEX=$(CAMLRUN) ../boot/ocamllex
+INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \
+ -I ../driver
+COMPFLAGS= -warn-error A $(INCLUDES)
+LINKFLAGS=$(INCLUDES)
+
+all: ocamldep ocamlprof ocamlcp ocamlmktop ocamlmklib dumpobj objinfo
+# scrapelabels addlabels
+
+.PHONY: all
+
+opt.opt: ocamldep.opt
+.PHONY: opt.opt
+
+# The dependency generator
+
+CAMLDEP_OBJ=depend.cmo ocamldep.cmo
+CAMLDEP_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \
+ linenum.cmo warnings.cmo location.cmo longident.cmo \
+ syntaxerr.cmo parser.cmo lexer.cmo parse.cmo
+
+ocamldep: depend.cmi $(CAMLDEP_OBJ)
+ $(CAMLC) $(LINKFLAGS) -o ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ)
+
+ocamldep.opt: depend.cmi $(CAMLDEP_OBJ:.cmo=.cmx)
+ $(CAMLOPT) $(LINKFLAGS) -o ocamldep.opt $(CAMLDEP_IMPORTS:.cmo=.cmx) \
+ $(CAMLDEP_OBJ:.cmo=.cmx)
+
+# ocamldep is precious: sometimes we are stuck in the middle of a
+# bootstrap and we need to remake the dependencies
+clean::
+ if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi
+ rm -f ocamldep.opt
+
+install::
+ cp ocamldep $(BINDIR)/ocamldep$(EXE)
+ if test -f ocamldep.opt; \
+ then cp ocamldep.opt $(BINDIR)/ocamldep.opt$(EXE); else :; fi
+
+# The profiler
+
+CSLPROF=ocamlprof.cmo
+CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \
+ linenum.cmo warnings.cmo location.cmo longident.cmo \
+ syntaxerr.cmo parser.cmo lexer.cmo parse.cmo
+
+ocamlprof: $(CSLPROF) profiling.cmo
+ $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF)
+
+ocamlcp: ocamlcp.cmo
+ $(CAMLC) $(LINKFLAGS) -o ocamlcp warnings.cmo main_args.cmo ocamlcp.cmo
+
+install::
+ cp ocamlprof $(BINDIR)/ocamlprof$(EXE)
+ cp ocamlcp $(BINDIR)/ocamlcp$(EXE)
+ cp profiling.cmi profiling.cmo $(LIBDIR)
+
+clean::
+ rm -f ocamlprof ocamlcp
+
+install::
+ cp ocamlmktop $(BINDIR)/ocamlmktop$(EXE)
+
+clean::
+ rm -f ocamlmktop
+
+# To help building mixed-mode libraries (Caml + C)
+
+ocamlmklib: myocamlbuild_config.cmo ocamlmklib.cmo
+ $(CAMLC) $(LINKFLAGS) -o ocamlmklib myocamlbuild_config.cmo \
+ ocamlmklib.cmo
+
+ocamlmklib.cmo: myocamlbuild_config.cmi
+
+myocamlbuild_config.cmi: myocamlbuild_config.cmo
+
+myocamlbuild_config.ml: ../config/Makefile ../build/mkmyocamlbuild_config.sh
+ ../build/mkmyocamlbuild_config.sh
+ cp ../myocamlbuild_config.ml .
+
+install::
+ cp ocamlmklib $(BINDIR)/ocamlmklib$(EXE)
+
+clean::
+ rm -f ocamlmklib
+
+ocamlmklib.ml: ocamlmklib.mlp ../config/Makefile
+ echo '(* THIS FILE IS GENERATED FROM ocamlmklib.mlp *)' >ocamlmklib.ml
+ sed -e "s|%%BINDIR%%|$(BINDIR)|" \
+ -e "s|%%SUPPORTS_SHARED_LIBRARIES%%|$(SUPPORTS_SHARED_LIBRARIES)|" \
+ -e "s|%%MKSHAREDLIB%%|$(MKSHAREDLIB)|" \
+ -e "s|%%BYTECCRPATH%%|$(BYTECCRPATH)|" \
+ -e "s|%%NATIVECCRPATH%%|$(NATIVECCRPATH)|" \
+ -e "s|%%MKSHAREDLIBRPATH%%|$(MKSHAREDLIBRPATH)|" \
+ -e "s|%%RANLIB%%|$(RANLIB)|" \
+ ocamlmklib.mlp >> ocamlmklib.ml
+
+beforedepend:: ocamlmklib.ml
+
+clean::
+ rm -f ocamlmklib.ml
+
+# To make custom toplevels (see Makefile/Makefile.nt)
+
+install::
+ cp ocamlmktop $(BINDIR)/ocamlmktop$(EXE)
+
+clean::
+ rm -f ocamlmktop
+
+
+# Converter olabl/ocaml 2.99 to ocaml 3
+
+OCAML299TO3= lexer299.cmo ocaml299to3.cmo
+LIBRARY3= misc.cmo warnings.cmo linenum.cmo location.cmo
+
+ocaml299to3: $(OCAML299TO3)
+ $(CAMLC) $(LINKFLAGS) -o ocaml299to3 $(LIBRARY3) $(OCAML299TO3)
+
+lexer299.ml: lexer299.mll
+ $(CAMLLEX) lexer299.mll
+
+#install::
+# cp ocaml299to3 $(BINDIR)/ocaml299to3$(EXE)
+
+clean::
+ rm -f ocaml299to3 lexer299.ml
+
+# Label remover for interface files (upgrade 3.02 to 3.03)
+
+SCRAPELABELS= lexer301.cmo scrapelabels.cmo
+
+scrapelabels: $(SCRAPELABELS)
+ $(CAMLC) $(LINKFLAGS) -o scrapelabels $(LIBRARY3) $(SCRAPELABELS)
+
+lexer301.ml: lexer301.mll
+ $(CAMLLEX) lexer301.mll
+
+#install::
+# cp scrapelabels $(LIBDIR)
+
+clean::
+ rm -f scrapelabels lexer301.ml
+
+# Insert labels following an interface file (upgrade 3.02 to 3.03)
+
+ADDLABELS_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \
+ linenum.cmo warnings.cmo location.cmo longident.cmo \
+ syntaxerr.cmo parser.cmo lexer.cmo parse.cmo
+
+addlabels: addlabels.cmo
+ $(CAMLC) $(LINKFLAGS) -w sl -o addlabels \
+ $(ADDLABELS_IMPORTS) addlabels.cmo
+
+#install::
+# cp addlabels $(LIBDIR)
+
+clean::
+ rm -f addlabels
+
+# The preprocessor for asm generators
+
+CVT_EMIT=cvt_emit.cmo
+
+cvt_emit: $(CVT_EMIT)
+ $(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT)
+
+# cvt_emit is precious: sometimes we are stuck in the middle of a
+# bootstrap and we need to remake the dependencies
+clean::
+ if test -f cvt_emit; then mv -f cvt_emit cvt_emit.bak; else :; fi
+
+cvt_emit.ml: cvt_emit.mll
+ $(CAMLLEX) cvt_emit.mll
+
+clean::
+ rm -f cvt_emit.ml
+
+beforedepend:: cvt_emit.ml
+
+# The bytecode disassembler
+
+DUMPOBJ=opnames.cmo dumpobj.cmo
+
+dumpobj: $(DUMPOBJ)
+ $(CAMLC) $(LINKFLAGS) -o dumpobj \
+ misc.cmo tbl.cmo config.cmo ident.cmo \
+ opcodes.cmo bytesections.cmo $(DUMPOBJ)
+
+clean::
+ rm -f dumpobj
+
+opnames.ml: ../byterun/instruct.h
+ unset LC_ALL || : ; \
+ unset LC_CTYPE || : ; \
+ unset LC_COLLATE LANG || : ; \
+ sed -e '/\/\*/d' \
+ -e '/^#/d' \
+ -e 's/enum \(.*\) {/let names_of_\1 = [|/' \
+ -e 's/};$$/ |]/' \
+ -e 's/\([A-Z][A-Z_0-9a-z]*\)/"\1"/g' \
+ -e 's/,/;/g' \
+ ../byterun/instruct.h > opnames.ml
+
+clean::
+ rm -f opnames.ml
+
+beforedepend:: opnames.ml
+
+# Display info on compiled files
+
+objinfo_helper$(EXE): objinfo_helper.c ../config/s.h
+ $(BYTECC) -o objinfo_helper$(EXE) $(BYTECCCOMPOPTS) \
+ objinfo_helper.c $(LIBBFD_LINK)
+
+OBJINFO=../utils/misc.cmo ../utils/config.cmo ../bytecomp/bytesections.cmo \
+ objinfo.cmo
+
+objinfo: objinfo_helper$(EXE) $(OBJINFO)
+ $(CAMLC) -o objinfo $(OBJINFO)
+
+install::
+ cp objinfo $(BINDIR)/ocamlobjinfo$(EXE)
+ cp objinfo_helper$(EXE) $(LIBDIR)/objinfo_helper$(EXE)
+
+clean::
+ rm -f objinfo objinfo_helper$(EXE)
+
+# Scan object files for required primitives
+
+PRIMREQ=primreq.cmo
+
+primreq: $(PRIMREQ)
+ $(CAMLC) $(LINKFLAGS) -o primreq config.cmo $(PRIMREQ)
+
+clean::
+ rm -f primreq
+
+# Common stuff
+
+.SUFFIXES:
+.SUFFIXES: .ml .cmo .mli .cmi .cmx
+
+.ml.cmo:
+ $(CAMLC) -c $(COMPFLAGS) $<
+
+.mli.cmi:
+ $(CAMLC) -c $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) $(COMPFLAGS) -c $<
+
+clean::
+ rm -f *.cmo *.cmi *.cma *.dll *.so *.lib *.a
+
+depend: beforedepend
+ $(CAMLRUN) ./ocamldep $(INCLUDES) *.mli *.ml > .depend
+
+.PHONY: clean install beforedepend depend
+
+include .depend
diff --git a/ocaml-binary-annot/tools/OCamlc-custom b/ocaml-binary-annot/tools/OCamlc-custom
new file mode 100644
index 0000000000..c389974e2b
--- /dev/null
+++ b/ocaml-binary-annot/tools/OCamlc-custom
@@ -0,0 +1,10 @@
+# OCamlc with option -custom
+# Macintosh version
+
+set echo 0
+set -e ocamlcommands "{tempfolder}"OCaml.temp."`date -n`"
+echo >"{ocamlcommands}"
+ocamlc -custom {"parameters"}
+execute "{ocamlcommands}"
+
+delete -y "{ocamlcommands}"
diff --git a/ocaml-binary-annot/tools/Time b/ocaml-binary-annot/tools/Time
new file mode 100644
index 0000000000..0a8267465b
--- /dev/null
+++ b/ocaml-binary-annot/tools/Time
@@ -0,0 +1,10 @@
+# Time # Measure execution time
+# Usage: Time command argumentsÉ
+
+set echo 0
+
+set startdate `date -n`
+{parameters}
+set enddate `date -n`
+
+echo "# Time: `evaluate {enddate} - {startdate}` s" > dev:stderr
diff --git a/ocaml-binary-annot/tools/addlabels.ml b/ocaml-binary-annot/tools/addlabels.ml
new file mode 100644
index 0000000000..6a297b9e86
--- /dev/null
+++ b/ocaml-binary-annot/tools/addlabels.ml
@@ -0,0 +1,453 @@
+(* $Id$ *)
+
+open StdLabels
+open Asttypes
+open Parsetree
+
+let norec = ref false
+
+let input_file file =
+ let ic = try open_in file with _ -> failwith ("input_file : " ^ file) in
+ let b = Buffer.create 1024 in
+ let buf = String.create 1024 and len = ref 0 in
+ while len := input ic buf 0 1024; !len > 0 do
+ Buffer.add_substring b buf 0 !len
+ done;
+ close_in ic;
+ Buffer.contents b
+
+module SMap = struct
+ include Map.Make(struct type t = string let compare = compare end)
+ let rec removes l m =
+ match l with [] -> m
+ | k::l ->
+ let m = try remove k m with Not_found -> m in
+ removes l m
+end
+
+let rec labels_of_sty sty =
+ match sty.ptyp_desc with
+ Ptyp_arrow (lab, _, rem) -> lab :: labels_of_sty rem
+ | Ptyp_alias (rem, _) -> labels_of_sty rem
+ | _ -> []
+
+let rec labels_of_cty cty =
+ match cty.pcty_desc with
+ Pcty_fun (lab, _, rem) ->
+ let (labs, meths) = labels_of_cty rem in
+ (lab :: labs, meths)
+ | Pcty_signature (_, fields) ->
+ ([],
+ List.fold_left fields ~init:[] ~f:
+ begin fun meths -> function
+ Pctf_meth (s, _, sty, _) -> (s, labels_of_sty sty)::meths
+ | _ -> meths
+ end)
+ | _ ->
+ ([],[])
+
+let rec pattern_vars pat =
+ match pat.ppat_desc with
+ Ppat_var s -> [s]
+ | Ppat_alias (pat, s) ->
+ s :: pattern_vars pat
+ | Ppat_tuple l
+ | Ppat_array l ->
+ List.concat (List.map pattern_vars l)
+ | Ppat_construct (_, Some pat, _)
+ | Ppat_variant (_, Some pat)
+ | Ppat_constraint (pat, _) ->
+ pattern_vars pat
+ | Ppat_record(l, _) ->
+ List.concat (List.map l ~f:(fun (_,p) -> pattern_vars p))
+ | Ppat_or (pat1, pat2) ->
+ pattern_vars pat1 @ pattern_vars pat2
+ | Ppat_lazy pat -> pattern_vars pat
+ | Ppat_any | Ppat_constant _ | Ppat_construct _ | Ppat_variant _
+ | Ppat_type _ | Ppat_unpack _ ->
+ []
+
+let pattern_name pat =
+ match pat.ppat_desc with
+ Ppat_var s -> Some s
+ | Ppat_constraint ({ppat_desc = Ppat_var s}, _) -> Some s
+ | _ -> None
+
+let insertions = ref []
+let add_insertion pos s = insertions := (pos,s) :: !insertions
+let sort_insertions () =
+ List.sort !insertions ~cmp:(fun (pos1,_) (pos2,_) -> pos1 - pos2)
+
+let is_space = function ' '|'\t'|'\n'|'\r' -> true | _ -> false
+let is_alphanum = function 'A'..'Z'|'a'..'z'|'_'|'\192'..'\214'|'\216'..'\246'
+ | '\248'..'\255'|'\''|'0'..'9' -> true
+ | _ -> false
+
+(* Remove "(" or "begin" before a pattern *)
+let rec insertion_point pos ~text =
+ let pos' = ref (pos-1) in
+ while is_space text.[!pos'] do decr pos' done;
+ if text.[!pos'] = '(' then insertion_point !pos' ~text else
+ if !pos' >= 5 && String.sub text ~pos:(!pos'-4) ~len:5 = "begin"
+ && not (is_alphanum text.[!pos'-5]) then insertion_point (!pos'-4) ~text
+ else pos
+
+(* Search "=" or "->" before "function" *)
+let rec insertion_point2 pos ~text =
+ let pos' = ref (pos-1) in
+ while is_space text.[!pos'] do decr pos' done;
+ if text.[!pos'] = '(' then insertion_point2 !pos' ~text else
+ if !pos' >= 5 && String.sub text ~pos:(!pos'-4) ~len:5 = "begin"
+ && not (is_alphanum text.[!pos'-5]) then insertion_point2 (!pos'-4) ~text
+ else if text.[!pos'] = '=' then Some !pos' else
+ if !pos' >= 1 && text.[!pos'-1] = '-' && text.[!pos'] = '>'
+ then Some (!pos' - 1)
+ else None
+
+let rec insert_labels ~labels ~text expr =
+ match labels, expr.pexp_desc with
+ l::labels, Pexp_function(l', _, [pat, rem]) ->
+ if l <> "" && l.[0] <> '?' && l' = "" then begin
+ let start_c = pat.ppat_loc.Location.loc_start.Lexing.pos_cnum in
+ let pos = insertion_point start_c ~text in
+ match pattern_name pat with
+ | Some name when l = name -> add_insertion pos "~"
+ | _ -> add_insertion pos ("~" ^ l ^ ":")
+ end;
+ insert_labels ~labels ~text rem
+ | l::labels, Pexp_function(l', _, lst) ->
+ let pos = expr.pexp_loc.Location.loc_start.Lexing.pos_cnum in
+ if l <> "" && l.[0] <> '?' && l' = ""
+ && String.sub text ~pos ~len:8 = "function" then begin
+ String.blit ~src:"match th" ~src_pos:0 ~dst:text
+ ~dst_pos:pos ~len:8;
+ add_insertion (pos+6) (l ^ " wi");
+ match insertion_point2 pos ~text with
+ Some pos' ->
+ add_insertion pos' ("~" ^ l ^ " ")
+ | None ->
+ add_insertion pos ("fun ~" ^ l ^ " -> ")
+ end;
+ List.iter lst ~f:(fun (p,e) -> insert_labels ~labels ~text e)
+ | _, Pexp_match( _, lst) ->
+ List.iter lst ~f:(fun (p,e) -> insert_labels ~labels ~text e)
+ | _, Pexp_try(expr, lst) ->
+ insert_labels ~labels ~text expr;
+ List.iter lst ~f:(fun (p,e) -> insert_labels ~labels ~text e)
+ | _, ( Pexp_let(_,_,e) | Pexp_sequence(_,e) | Pexp_when(_,e)
+ | Pexp_constraint(e,_,_) | Pexp_letmodule(_,_,e)
+ | Pexp_ifthenelse(_,e,None) ) ->
+ insert_labels ~labels ~text e
+ | _, Pexp_ifthenelse (_, e1, Some e2) ->
+ insert_labels ~labels ~text e1;
+ insert_labels ~labels ~text e2
+ | _ ->
+ ()
+
+let rec insert_labels_class ~labels ~text expr =
+ match labels, expr.pcl_desc with
+ l::labels, Pcl_fun(l', _, pat, rem) ->
+ if l <> "" && l.[0] <> '?' && l' = "" then begin
+ let start_c = pat.ppat_loc.Location.loc_start.Lexing.pos_cnum in
+ let pos = insertion_point start_c ~text in
+ match pattern_name pat with
+ | Some name when l = name -> add_insertion pos "~"
+ | _ -> add_insertion pos ("~" ^ l ^ ":")
+ end;
+ insert_labels_class ~labels ~text rem
+ | labels, (Pcl_constraint (expr, _) | Pcl_let (_, _, expr)) ->
+ insert_labels_class ~labels ~text expr
+ | _ ->
+ ()
+
+let rec insert_labels_type ~labels ~text ty =
+ match labels, ty.ptyp_desc with
+ l::labels, Ptyp_arrow(l', _, rem) ->
+ if l <> "" && l.[0] <> '?' && l' = "" then begin
+ let start_c = ty.ptyp_loc.Location.loc_start.Lexing.pos_cnum in
+ let pos = insertion_point start_c ~text in
+ add_insertion pos (l ^ ":")
+ end;
+ insert_labels_type ~labels ~text rem
+ | _ ->
+ ()
+
+let rec insert_labels_app ~labels ~text args =
+ match labels, args with
+ l::labels, (l',arg)::args ->
+ if l <> "" && l.[0] <> '?' && l' = "" then begin
+ let pos0 = arg.pexp_loc.Location.loc_start.Lexing.pos_cnum in
+ let pos = insertion_point pos0 ~text in
+ match arg.pexp_desc with
+ | Pexp_ident(Longident.Lident name) when l = name && pos = pos0 ->
+ add_insertion pos "~"
+ | _ -> add_insertion pos ("~" ^ l ^ ":")
+ end;
+ insert_labels_app ~labels ~text args
+ | _ ->
+ ()
+
+let insert_labels_app ~labels ~text args =
+ let labels, opt_labels =
+ List.partition labels ~f:(fun l -> l = "" || l.[0] <> '?') in
+ let nopt_labels =
+ List.map opt_labels
+ ~f:(fun l -> String.sub l ~pos:1 ~len:(String.length l - 1)) in
+ (* avoid ambiguous labels *)
+ if List.exists labels ~f:(List.mem ~set:nopt_labels) then () else
+ let aopt_labels = opt_labels @ nopt_labels in
+ let args, lab_args = List.partition args ~f:(fun (l,_) -> l = "") in
+ (* only optional arguments are labeled *)
+ if List.for_all lab_args ~f:(fun (l,_) -> List.mem l ~set:aopt_labels)
+ then insert_labels_app ~labels ~text args
+
+let rec add_labels_expr ~text ~values ~classes expr =
+ let add_labels_rec ?(values=values) expr =
+ add_labels_expr ~text ~values ~classes expr in
+ match expr.pexp_desc with
+ Pexp_apply ({pexp_desc=Pexp_ident(Longident.Lident s)}, args) ->
+ begin try
+ let labels = SMap.find s values in
+ insert_labels_app ~labels ~text args
+ with Not_found -> ()
+ end;
+ List.iter args ~f:(fun (_,e) -> add_labels_rec e)
+ | Pexp_apply ({pexp_desc=Pexp_send
+ ({pexp_desc=Pexp_ident(Longident.Lident s)},meth)}, args) ->
+ begin try
+ if SMap.find s values = ["<object>"] then
+ let labels = SMap.find (s ^ "#" ^ meth) values in
+ insert_labels_app ~labels ~text args
+ with Not_found -> ()
+ end
+ | Pexp_apply ({pexp_desc=Pexp_new (Longident.Lident s)}, args) ->
+ begin try
+ let labels = SMap.find s classes in
+ insert_labels_app ~labels ~text args
+ with Not_found -> ()
+ end
+ | Pexp_let (recp, lst, expr) ->
+ let vars = List.concat (List.map lst ~f:(fun (p,_) -> pattern_vars p)) in
+ let vals = SMap.removes vars values in
+ List.iter lst ~f:
+ begin fun (_,e) ->
+ add_labels_rec e ~values:(if recp = Recursive then vals else values)
+ end;
+ add_labels_rec expr ~values:vals
+ | Pexp_function (_, None, lst) ->
+ List.iter lst ~f:
+ (fun (p,e) ->
+ add_labels_rec e ~values:(SMap.removes (pattern_vars p) values))
+ | Pexp_function (_, Some e, lst)
+ | Pexp_match (e, lst)
+ | Pexp_try (e, lst) ->
+ add_labels_rec e;
+ List.iter lst ~f:
+ (fun (p,e) ->
+ add_labels_rec e ~values:(SMap.removes (pattern_vars p) values))
+ | Pexp_apply (e, args) ->
+ List.iter add_labels_rec (e :: List.map snd args)
+ | Pexp_tuple l | Pexp_array l ->
+ List.iter add_labels_rec l
+ | Pexp_construct (_, Some e, _)
+ | Pexp_variant (_, Some e)
+ | Pexp_field (e, _)
+ | Pexp_constraint (e, _, _)
+ | Pexp_send (e, _)
+ | Pexp_setinstvar (_, e)
+ | Pexp_letmodule (_, _, e)
+ | Pexp_assert e
+ | Pexp_lazy e
+ | Pexp_poly (e, _)
+ | Pexp_newtype (_, e)
+ | Pexp_open (_, e) ->
+ add_labels_rec e
+ | Pexp_record (lst, opt) ->
+ List.iter lst ~f:(fun (_,e) -> add_labels_rec e);
+ begin match opt with Some e -> add_labels_rec e | None -> () end
+ | Pexp_setfield (e1, _, e2)
+ | Pexp_ifthenelse (e1, e2, None)
+ | Pexp_sequence (e1, e2)
+ | Pexp_while (e1, e2)
+ | Pexp_when (e1, e2) ->
+ add_labels_rec e1; add_labels_rec e2
+ | Pexp_ifthenelse (e1, e2, Some e3) ->
+ add_labels_rec e1; add_labels_rec e2; add_labels_rec e3
+ | Pexp_for (s, e1, e2, _, e3) ->
+ add_labels_rec e1; add_labels_rec e2;
+ add_labels_rec e3 ~values:(SMap.removes [s] values)
+ | Pexp_override lst ->
+ List.iter lst ~f:(fun (_,e) -> add_labels_rec e)
+ | Pexp_ident _ | Pexp_constant _ | Pexp_construct _ | Pexp_variant _
+ | Pexp_new _ | Pexp_assertfalse | Pexp_object _ | Pexp_pack _ ->
+ ()
+
+let rec add_labels_class ~text ~classes ~values ~methods cl =
+ match cl.pcl_desc with
+ Pcl_constr _ -> ()
+ | Pcl_structure (p, l) ->
+ let values = SMap.removes (pattern_vars p) values in
+ let values =
+ match pattern_name p with None -> values
+ | Some s ->
+ List.fold_left methods
+ ~init:(SMap.add s ["<object>"] values)
+ ~f:(fun m (k,l) -> SMap.add (s^"#"^k) l m)
+ in
+ ignore (List.fold_left l ~init:values ~f:
+ begin fun values -> function
+ | Pcf_val (s, _, _, e, _) ->
+ add_labels_expr ~text ~classes ~values e;
+ SMap.removes [s] values
+ | Pcf_meth (s, _, _, e, _) ->
+ begin try
+ let labels = List.assoc s methods in
+ insert_labels ~labels ~text e
+ with Not_found -> ()
+ end;
+ add_labels_expr ~text ~classes ~values e;
+ values
+ | Pcf_init e ->
+ add_labels_expr ~text ~classes ~values e;
+ values
+ | Pcf_inher _ | Pcf_valvirt _ | Pcf_virt _ | Pcf_cstr _ -> values
+ | Pcf_let _ -> values (* not in the grammar *)
+ end)
+ | Pcl_fun (_, opt, pat, cl) ->
+ begin match opt with None -> ()
+ | Some e -> add_labels_expr ~text ~classes ~values e
+ end;
+ let values = SMap.removes (pattern_vars pat) values in
+ add_labels_class ~text ~classes ~values ~methods cl
+ | Pcl_apply (cl, args) ->
+ List.iter args ~f:(fun (_,e) -> add_labels_expr ~text ~classes ~values e);
+ add_labels_class ~text ~classes ~values ~methods cl
+ | Pcl_let (recp, lst, cl) ->
+ let vars = List.concat (List.map lst ~f:(fun (p,_) -> pattern_vars p)) in
+ let vals = SMap.removes vars values in
+ List.iter lst ~f:
+ begin fun (_,e) ->
+ add_labels_expr e ~text ~classes
+ ~values:(if recp = Recursive then vals else values)
+ end;
+ add_labels_class cl ~text ~classes ~values:vals ~methods
+ | Pcl_constraint (cl, _) ->
+ add_labels_class ~text ~classes ~values ~methods cl
+
+let add_labels ~intf ~impl ~file =
+ insertions := [];
+ let values, classes =
+ List.fold_left intf ~init:(SMap.empty, SMap.empty) ~f:
+ begin fun (values, classes as acc) item ->
+ match item.psig_desc with
+ Psig_value (name, {pval_type = sty}) ->
+ (SMap.add name (labels_of_sty sty) values, classes)
+ | Psig_class l ->
+ (values,
+ List.fold_left l ~init:classes ~f:
+ begin fun classes {pci_name=name; pci_expr=cty} ->
+ SMap.add name (labels_of_cty cty) classes
+ end)
+ | _ ->
+ acc
+ end
+ in
+ let text = input_file file in
+ ignore (List.fold_right impl ~init:(values, classes) ~f:
+ begin fun item (values, classes as acc) ->
+ match item.pstr_desc with
+ Pstr_value (recp, l) ->
+ let names =
+ List.concat (List.map l ~f:(fun (p,_) -> pattern_vars p)) in
+ List.iter l ~f:
+ begin fun (pat, expr) ->
+ begin match pattern_name pat with
+ | Some s ->
+ begin try
+ let labels = SMap.find s values in
+ insert_labels ~labels ~text expr;
+ if !norec then () else
+ let values =
+ SMap.fold
+ (fun s l m ->
+ if List.mem s names then SMap.add s l m else m)
+ values SMap.empty in
+ add_labels_expr expr ~text ~values ~classes:SMap.empty
+ with Not_found -> ()
+ end
+ | None -> ()
+ end;
+ end;
+ (SMap.removes names values, classes)
+ | Pstr_primitive (s, {pval_type=sty}) ->
+ begin try
+ let labels = SMap.find s values in
+ insert_labels_type ~labels ~text sty;
+ (SMap.removes [s] values, classes)
+ with Not_found -> acc
+ end
+ | Pstr_class l ->
+ let names = List.map l ~f:(fun pci -> pci.pci_name) in
+ List.iter l ~f:
+ begin fun {pci_name=name; pci_expr=expr} ->
+ try
+ let (labels, methods) = SMap.find name classes in
+ insert_labels_class ~labels ~text expr;
+ if !norec then () else
+ let classes =
+ SMap.fold
+ (fun s (l,_) m ->
+ if List.mem s names then SMap.add s l m else m)
+ classes SMap.empty in
+ add_labels_class expr ~text ~classes ~methods
+ ~values:SMap.empty
+ with Not_found -> ()
+ end;
+ (values, SMap.removes names classes)
+ | _ ->
+ acc
+ end);
+ if !insertions <> [] then begin
+ let backup = file ^ ".bak" in
+ if Sys.file_exists backup then Sys.remove file
+ else Sys.rename file backup;
+ let oc = open_out file in
+ let last_pos =
+ List.fold_left (sort_insertions ()) ~init:0 ~f:
+ begin fun pos (pos', s) ->
+ output oc text pos (pos'-pos);
+ output_string oc s;
+ pos'
+ end in
+ if last_pos < String.length text then
+ output oc text last_pos (String.length text - last_pos);
+ close_out oc
+ end
+ else prerr_endline ("No labels to insert in " ^ file)
+
+let process_file file =
+ prerr_endline ("Processing " ^ file);
+ if Filename.check_suffix file ".ml" then
+ let intf = Filename.chop_suffix file ".ml" ^ ".mli" in
+ let ic = open_in intf in
+ let lexbuf = Lexing.from_channel ic in
+ Location.init lexbuf intf;
+ let intf = Parse.interface lexbuf in
+ close_in ic;
+ let ic = open_in file in
+ let lexbuf = Lexing.from_channel ic in
+ Location.init lexbuf file;
+ let impl = Parse.implementation lexbuf in
+ close_in ic;
+ add_labels ~intf ~impl ~file
+ else prerr_endline (file ^ " is not an implementation")
+
+let main () =
+ let files = ref [] in
+ Arg.parse ["-norec", Arg.Set norec, "do not labelize recursive calls"]
+ (fun f -> files := f :: !files)
+ "addlabels [-norec] <files>";
+ let files = List.rev !files in
+ List.iter files ~f:process_file
+
+let () = main ()
diff --git a/ocaml-binary-annot/tools/checkstack.c b/ocaml-binary-annot/tools/checkstack.c
new file mode 100644
index 0000000000..fc760945fc
--- /dev/null
+++ b/ocaml-binary-annot/tools/checkstack.c
@@ -0,0 +1,43 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Damien Doligez, projet Moscova, INRIA Rocquencourt */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique. All rights reserved. This file is distributed */
+/* under the terms of the GNU Library General Public License, with */
+/* the special exception on linking described in file ../../LICENSE. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#define MINSTACKBYTES (384 * 1024 * sizeof (long))
+
+int main(int argc, char ** argv)
+{
+ struct rlimit limit;
+ int rc;
+
+ rc = getrlimit (RLIMIT_STACK, &limit);
+ if (rc != 0) exit (0);
+ if (limit.rlim_cur < MINSTACKBYTES){
+ fprintf (stderr,
+ "\nThe current stack size limit is too low (%luk)\n"
+ "You must increase it with one of the following commands:\n"
+ "Under sh, bash, zsh: ulimit -s %lu\n"
+ "Under csh, tcsh: limit stacksize %lu\n\n",
+ (unsigned long) (limit.rlim_cur / 1024),
+ (unsigned long) (MINSTACKBYTES / 1024),
+ (unsigned long) (MINSTACKBYTES / 1024));
+ exit (3);
+ }
+ exit (0);
+}
diff --git a/ocaml-binary-annot/tools/cleanup-header b/ocaml-binary-annot/tools/cleanup-header
new file mode 100644
index 0000000000..6c320fb39c
--- /dev/null
+++ b/ocaml-binary-annot/tools/cleanup-header
@@ -0,0 +1,13 @@
+#!/bin/sed -f
+# Remove private parts from runtime include files, before installation
+# in /usr/local/lib/ocaml/caml
+
+/\/\* <include \.\.\/config\/m\.h> \*\// {
+ r ../config/m.h
+ d
+}
+/\/\* <include \.\.\/config\/s\.h> \*\// {
+ r ../config/s.h
+ d
+}
+/\/\* <private> \*\//,/\/\* <\/private> \*\//d
diff --git a/ocaml-binary-annot/tools/cvt_emit.mll b/ocaml-binary-annot/tools/cvt_emit.mll
new file mode 100644
index 0000000000..3e28ae9722
--- /dev/null
+++ b/ocaml-binary-annot/tools/cvt_emit.mll
@@ -0,0 +1,84 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+{
+let first_item = ref false
+let command_beginning = ref 0
+
+let add_semicolon () =
+ if !first_item
+ then first_item := false
+ else print_string "; "
+
+let print_unescaped_string s =
+ let l = String.length s in
+ let i = ref 0 in
+ while !i < l do
+ if s.[!i] = '\\'
+ && !i+1 < l
+ && (let c = s.[!i+1] in c = '{' || c = '`') (* ` *)
+ then i := !i+1;
+ print_char s.[!i];
+ i := !i + 1
+ done
+}
+
+rule main = parse
+ "`" { command_beginning := Lexing.lexeme_start lexbuf;
+ first_item := true;
+ print_char '(';
+ command lexbuf;
+ print_char ')';
+ main lexbuf }
+ | "\\`"
+ { print_string "`"; main lexbuf }
+ | eof { () }
+ | _ { print_char(Lexing.lexeme_char lexbuf 0); main lexbuf }
+
+and command = parse
+ "`" { () }
+ | eof { prerr_string "Unterminated `...` at character ";
+ prerr_int !command_beginning;
+ prerr_newline();
+ exit 2 }
+ | "{" [^ '}'] * "}"
+ { let s = Lexing.lexeme lexbuf in
+ add_semicolon();
+ print_string (String.sub s 1 (String.length s - 2));
+ command lexbuf }
+ | ( [^ '`' '{' '\\'] |
+ '\\' ['\\' '"' 'n' 't' 'b' 'r' '`' '{' ] |
+ '\\' ['0'-'9'] ['0'-'9'] ['0'-'9'] ) +
+ { let s = Lexing.lexeme lexbuf in
+ add_semicolon();
+ (* Optimise one-character strings *)
+ if String.length s = 1 && s.[0] <> '\\' && s.[0] <> '\''
+ || String.length s = 2 && s.[0] = '\\' && s.[1] <> '`' && s.[1]<>'{'
+ (* ` *)
+ then begin
+ print_string "emit_char '";
+ print_unescaped_string s;
+ print_string "'"
+ end else begin
+ print_string "emit_string \"";
+ print_unescaped_string s;
+ print_string "\""
+ end;
+ command lexbuf }
+
+{
+let _ = main(Lexing.from_channel stdin)
+
+let _ = exit (0)
+}
diff --git a/ocaml-binary-annot/tools/depend.ml b/ocaml-binary-annot/tools/depend.ml
new file mode 100644
index 0000000000..4a0da760b2
--- /dev/null
+++ b/ocaml-binary-annot/tools/depend.ml
@@ -0,0 +1,306 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1999 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Format
+open Location
+open Longident
+open Parsetree
+
+module StringSet = Set.Make(struct type t = string let compare = compare end)
+
+(* Collect free module identifiers in the a.s.t. *)
+
+let free_structure_names = ref StringSet.empty
+
+let rec addmodule bv lid =
+ match lid with
+ Lident s ->
+ if not (StringSet.mem s bv)
+ then free_structure_names := StringSet.add s !free_structure_names
+ | Ldot(l, s) -> addmodule bv l
+ | Lapply(l1, l2) -> addmodule bv l1; addmodule bv l2
+
+let add bv lid =
+ match lid with
+ Ldot(l, s) -> addmodule bv l
+ | _ -> ()
+
+let rec add_type bv ty =
+ match ty.ptyp_desc with
+ Ptyp_any -> ()
+ | Ptyp_var v -> ()
+ | Ptyp_arrow(_, t1, t2) -> add_type bv t1; add_type bv t2
+ | Ptyp_tuple tl -> List.iter (add_type bv) tl
+ | Ptyp_constr(c, tl) -> add bv c; List.iter (add_type bv) tl
+ | Ptyp_object fl -> List.iter (add_field_type bv) fl
+ | Ptyp_class(c, tl, _) -> add bv c; List.iter (add_type bv) tl
+ | Ptyp_alias(t, s) -> add_type bv t
+ | Ptyp_variant(fl, _, _) ->
+ List.iter
+ (function Rtag(_,_,stl) -> List.iter (add_type bv) stl
+ | Rinherit sty -> add_type bv sty)
+ fl
+ | Ptyp_poly(_, t) -> add_type bv t
+ | Ptyp_package pt -> add_package_type bv pt
+
+and add_package_type bv (lid, l) =
+ add bv lid;
+ List.iter (add_type bv) (List.map snd l)
+
+and add_field_type bv ft =
+ match ft.pfield_desc with
+ Pfield(name, ty) -> add_type bv ty
+ | Pfield_var -> ()
+
+let add_opt add_fn bv = function
+ None -> ()
+ | Some x -> add_fn bv x
+
+let add_type_declaration bv td =
+ List.iter
+ (fun (ty1, ty2, _) -> add_type bv ty1; add_type bv ty2)
+ td.ptype_cstrs;
+ add_opt add_type bv td.ptype_manifest;
+ let rec add_tkind = function
+ Ptype_abstract -> ()
+ | Ptype_variant cstrs ->
+ List.iter (fun (c, args, _) -> List.iter (add_type bv) args) cstrs
+ | Ptype_record lbls ->
+ List.iter (fun (l, mut, ty, _) -> add_type bv ty) lbls in
+ add_tkind td.ptype_kind
+
+let rec add_class_type bv cty =
+ match cty.pcty_desc with
+ Pcty_constr(l, tyl) ->
+ add bv l; List.iter (add_type bv) tyl
+ | Pcty_signature (ty, fieldl) ->
+ add_type bv ty;
+ List.iter (add_class_type_field bv) fieldl
+ | Pcty_fun(_, ty1, cty2) ->
+ add_type bv ty1; add_class_type bv cty2
+
+and add_class_type_field bv = function
+ Pctf_inher cty -> add_class_type bv cty
+ | Pctf_val(_, _, _, ty, _) -> add_type bv ty
+ | Pctf_virt(_, _, ty, _) -> add_type bv ty
+ | Pctf_meth(_, _, ty, _) -> add_type bv ty
+ | Pctf_cstr(ty1, ty2, _) -> add_type bv ty1; add_type bv ty2
+
+let add_class_description bv infos =
+ add_class_type bv infos.pci_expr
+
+let add_class_type_declaration = add_class_description
+
+let rec add_pattern bv pat =
+ match pat.ppat_desc with
+ Ppat_any -> ()
+ | Ppat_var _ -> ()
+ | Ppat_alias(p, _) -> add_pattern bv p
+ | Ppat_constant _ -> ()
+ | Ppat_tuple pl -> List.iter (add_pattern bv) pl
+ | Ppat_construct(c, op, _) -> add bv c; add_opt add_pattern bv op
+ | Ppat_record(pl, _) ->
+ List.iter (fun (lbl, p) -> add bv lbl; add_pattern bv p) pl
+ | Ppat_array pl -> List.iter (add_pattern bv) pl
+ | Ppat_or(p1, p2) -> add_pattern bv p1; add_pattern bv p2
+ | Ppat_constraint(p, ty) -> add_pattern bv p; add_type bv ty
+ | Ppat_variant(_, op) -> add_opt add_pattern bv op
+ | Ppat_type (li) -> add bv li
+ | Ppat_lazy p -> add_pattern bv p
+ | Ppat_unpack _ -> ()
+
+let rec add_expr bv exp =
+ match exp.pexp_desc with
+ Pexp_ident l -> add bv l
+ | Pexp_constant _ -> ()
+ | Pexp_let(_, pel, e) -> add_pat_expr_list bv pel; add_expr bv e
+ | Pexp_function (_, opte, pel) ->
+ add_opt add_expr bv opte; add_pat_expr_list bv pel
+ | Pexp_apply(e, el) ->
+ add_expr bv e; List.iter (fun (_,e) -> add_expr bv e) el
+ | Pexp_match(e, pel) -> add_expr bv e; add_pat_expr_list bv pel
+ | Pexp_try(e, pel) -> add_expr bv e; add_pat_expr_list bv pel
+ | Pexp_tuple el -> List.iter (add_expr bv) el
+ | Pexp_construct(c, opte, _) -> add bv c; add_opt add_expr bv opte
+ | Pexp_variant(_, opte) -> add_opt add_expr bv opte
+ | Pexp_record(lblel, opte) ->
+ List.iter (fun (lbl, e) -> add bv lbl; add_expr bv e) lblel;
+ add_opt add_expr bv opte
+ | Pexp_field(e, fld) -> add_expr bv e; add bv fld
+ | Pexp_setfield(e1, fld, e2) -> add_expr bv e1; add bv fld; add_expr bv e2
+ | Pexp_array el -> List.iter (add_expr bv) el
+ | Pexp_ifthenelse(e1, e2, opte3) ->
+ add_expr bv e1; add_expr bv e2; add_opt add_expr bv opte3
+ | Pexp_sequence(e1, e2) -> add_expr bv e1; add_expr bv e2
+ | Pexp_while(e1, e2) -> add_expr bv e1; add_expr bv e2
+ | Pexp_for(_, e1, e2, _, e3) ->
+ add_expr bv e1; add_expr bv e2; add_expr bv e3
+ | Pexp_constraint(e1, oty2, oty3) ->
+ add_expr bv e1;
+ add_opt add_type bv oty2;
+ add_opt add_type bv oty3
+ | Pexp_when(e1, e2) -> add_expr bv e1; add_expr bv e2
+ | Pexp_send(e, m) -> add_expr bv e
+ | Pexp_new l -> add bv l
+ | Pexp_setinstvar(v, e) -> add_expr bv e
+ | Pexp_override sel -> List.iter (fun (s, e) -> add_expr bv e) sel
+ | Pexp_letmodule(id, m, e) ->
+ add_module bv m; add_expr (StringSet.add id bv) e
+ | Pexp_assert (e) -> add_expr bv e
+ | Pexp_assertfalse -> ()
+ | Pexp_lazy (e) -> add_expr bv e
+ | Pexp_poly (e, t) -> add_expr bv e; add_opt add_type bv t
+ | Pexp_object (pat, fieldl) ->
+ add_pattern bv pat; List.iter (add_class_field bv) fieldl
+ | Pexp_newtype (_, e) -> add_expr bv e
+ | Pexp_pack m -> add_module bv m
+ | Pexp_open (m, e) -> addmodule bv m; add_expr bv e
+and add_pat_expr_list bv pel =
+ List.iter (fun (p, e) -> add_pattern bv p; add_expr bv e) pel
+
+and add_modtype bv mty =
+ match mty.pmty_desc with
+ Pmty_ident l -> add bv l
+ | Pmty_signature s -> add_signature bv s
+ | Pmty_functor(id, mty1, mty2) ->
+ add_modtype bv mty1; add_modtype (StringSet.add id bv) mty2
+ | Pmty_with(mty, cstrl) ->
+ add_modtype bv mty;
+ List.iter
+ (function (_, Pwith_type td) -> add_type_declaration bv td
+ | (_, Pwith_module lid) -> addmodule bv lid
+ | (_, Pwith_typesubst td) -> add_type_declaration bv td
+ | (_, Pwith_modsubst lid) -> addmodule bv lid)
+ cstrl
+ | Pmty_typeof m -> add_module bv m
+
+and add_signature bv = function
+ [] -> ()
+ | item :: rem -> add_signature (add_sig_item bv item) rem
+
+and add_sig_item bv item =
+ match item.psig_desc with
+ Psig_value(id, vd) ->
+ add_type bv vd.pval_type; bv
+ | Psig_type dcls ->
+ List.iter (fun (id, td) -> add_type_declaration bv td) dcls; bv
+ | Psig_exception(id, args) ->
+ List.iter (add_type bv) args; bv
+ | Psig_module(id, mty) ->
+ add_modtype bv mty; StringSet.add id bv
+ | Psig_recmodule decls ->
+ let bv' = List.fold_right StringSet.add (List.map fst decls) bv in
+ List.iter (fun (id, mty) -> add_modtype bv' mty) decls;
+ bv'
+ | Psig_modtype(id, mtyd) ->
+ begin match mtyd with
+ Pmodtype_abstract -> ()
+ | Pmodtype_manifest mty -> add_modtype bv mty
+ end;
+ bv
+ | Psig_open lid ->
+ addmodule bv lid; bv
+ | Psig_include mty ->
+ add_modtype bv mty; bv
+ | Psig_class cdl ->
+ List.iter (add_class_description bv) cdl; bv
+ | Psig_class_type cdtl ->
+ List.iter (add_class_type_declaration bv) cdtl; bv
+
+and add_module bv modl =
+ match modl.pmod_desc with
+ Pmod_ident l -> addmodule bv l
+ | Pmod_structure s -> ignore (add_structure bv s)
+ | Pmod_functor(id, mty, modl) ->
+ add_modtype bv mty;
+ add_module (StringSet.add id bv) modl
+ | Pmod_apply(mod1, mod2) ->
+ add_module bv mod1; add_module bv mod2
+ | Pmod_constraint(modl, mty) ->
+ add_module bv modl; add_modtype bv mty
+ | Pmod_unpack(e) ->
+ add_expr bv e
+
+and add_structure bv item_list =
+ List.fold_left add_struct_item bv item_list
+
+and add_struct_item bv item =
+ match item.pstr_desc with
+ Pstr_eval e ->
+ add_expr bv e; bv
+ | Pstr_value(id, pel) ->
+ add_pat_expr_list bv pel; bv
+ | Pstr_primitive(id, vd) ->
+ add_type bv vd.pval_type; bv
+ | Pstr_type dcls ->
+ List.iter (fun (id, td) -> add_type_declaration bv td) dcls; bv
+ | Pstr_exception(id, args) ->
+ List.iter (add_type bv) args; bv
+ | Pstr_exn_rebind(id, l) ->
+ add bv l; bv
+ | Pstr_module(id, modl) ->
+ add_module bv modl; StringSet.add id bv
+ | Pstr_recmodule bindings ->
+ let bv' =
+ List.fold_right StringSet.add
+ (List.map (fun (id,_,_) -> id) bindings) bv in
+ List.iter
+ (fun (id, mty, modl) -> add_modtype bv' mty; add_module bv' modl)
+ bindings;
+ bv'
+ | Pstr_modtype(id, mty) ->
+ add_modtype bv mty; bv
+ | Pstr_open l ->
+ addmodule bv l; bv
+ | Pstr_class cdl ->
+ List.iter (add_class_declaration bv) cdl; bv
+ | Pstr_class_type cdtl ->
+ List.iter (add_class_type_declaration bv) cdtl; bv
+ | Pstr_include modl ->
+ add_module bv modl; bv
+
+and add_use_file bv top_phrs =
+ ignore (List.fold_left add_top_phrase bv top_phrs)
+
+and add_top_phrase bv = function
+ | Ptop_def str -> add_structure bv str
+ | Ptop_dir (_, _) -> bv
+
+and add_class_expr bv ce =
+ match ce.pcl_desc with
+ Pcl_constr(l, tyl) ->
+ add bv l; List.iter (add_type bv) tyl
+ | Pcl_structure(pat, fieldl) ->
+ add_pattern bv pat; List.iter (add_class_field bv) fieldl
+ | Pcl_fun(_, opte, pat, ce) ->
+ add_opt add_expr bv opte; add_pattern bv pat; add_class_expr bv ce
+ | Pcl_apply(ce, exprl) ->
+ add_class_expr bv ce; List.iter (fun (_,e) -> add_expr bv e) exprl
+ | Pcl_let(_, pel, ce) ->
+ add_pat_expr_list bv pel; add_class_expr bv ce
+ | Pcl_constraint(ce, ct) ->
+ add_class_expr bv ce; add_class_type bv ct
+
+and add_class_field bv = function
+ Pcf_inher(_, ce, _) -> add_class_expr bv ce
+ | Pcf_val(_, _, _, e, _) -> add_expr bv e
+ | Pcf_valvirt(_, _, ty, _)
+ | Pcf_virt(_, _, ty, _) -> add_type bv ty
+ | Pcf_meth(_, _, _, e, _) -> add_expr bv e
+ | Pcf_cstr(ty1, ty2, _) -> add_type bv ty1; add_type bv ty2
+ | Pcf_let(_, pel, _) -> add_pat_expr_list bv pel
+ | Pcf_init e -> add_expr bv e
+
+and add_class_declaration bv decl =
+ add_class_expr bv decl.pci_expr
diff --git a/ocaml-binary-annot/tools/depend.mli b/ocaml-binary-annot/tools/depend.mli
new file mode 100644
index 0000000000..a13870610b
--- /dev/null
+++ b/ocaml-binary-annot/tools/depend.mli
@@ -0,0 +1,23 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1999 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(** Module dependencies. *)
+
+module StringSet : Set.S with type elt = string
+
+val free_structure_names : StringSet.t ref
+
+val add_use_file : StringSet.t -> Parsetree.toplevel_phrase list -> unit
+
+val add_signature : StringSet.t -> Parsetree.signature -> unit
diff --git a/ocaml-binary-annot/tools/dumpobj.ml b/ocaml-binary-annot/tools/dumpobj.ml
new file mode 100644
index 0000000000..2a054ee684
--- /dev/null
+++ b/ocaml-binary-annot/tools/dumpobj.ml
@@ -0,0 +1,560 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Disassembler for executable and .cmo object files *)
+
+open Asttypes
+open Config
+open Emitcode
+open Instruct
+open Lambda
+open Location
+open Obj
+open Opcodes
+open Opnames
+open Cmo_format
+open Printf
+
+(* Read signed and unsigned integers *)
+
+let inputu ic =
+ let b1 = input_byte ic in
+ let b2 = input_byte ic in
+ let b3 = input_byte ic in
+ let b4 = input_byte ic in
+ (b4 lsl 24) + (b3 lsl 16) + (b2 lsl 8) + b1
+
+let inputs ic =
+ let b1 = input_byte ic in
+ let b2 = input_byte ic in
+ let b3 = input_byte ic in
+ let b4 = input_byte ic in
+ let b4' = if b4 >= 128 then b4-256 else b4 in
+ (b4' lsl 24) + (b3 lsl 16) + (b2 lsl 8) + b1
+
+(* Global variables *)
+
+type global_table_entry =
+ Empty
+ | Global of Ident.t
+ | Constant of Obj.t
+
+let start = ref 0 (* Position of beg. of code *)
+let reloc = ref ([] : (reloc_info * int) list) (* Relocation table *)
+let globals = ref ([||] : global_table_entry array) (* Global map *)
+let primitives = ref ([||] : string array) (* Table of primitives *)
+let objfile = ref false (* true if dumping a .cmo *)
+
+(* Events (indexed by PC) *)
+
+let event_table = (Hashtbl.create 253 : (int, debug_event) Hashtbl.t)
+
+let relocate_event orig ev =
+ ev.ev_pos <- orig + ev.ev_pos;
+ match ev.ev_repr with
+ Event_parent repr -> repr := ev.ev_pos
+ | _ -> ()
+
+let record_events orig evl =
+ List.iter
+ (fun ev ->
+ relocate_event orig ev;
+ Hashtbl.add event_table ev.ev_pos ev)
+ evl
+
+(* Print a structured constant *)
+
+let print_float f =
+ if String.contains f '.'
+ then printf "%s" f
+ else printf "%s." f
+;;
+
+let rec print_struct_const = function
+ Const_base(Const_int i) -> printf "%d" i
+ | Const_base(Const_float f) -> print_float f
+ | Const_base(Const_string s) -> printf "%S" s
+ | Const_immstring s -> printf "%S" s
+ | Const_base(Const_char c) -> printf "%C" c
+ | Const_base(Const_int32 i) -> printf "%ldl" i
+ | Const_base(Const_nativeint i) -> printf "%ndn" i
+ | Const_base(Const_int64 i) -> printf "%LdL" i
+ | Const_pointer n -> printf "%da" n
+ | Const_block(tag, args) ->
+ printf "<%d>" tag;
+ begin match args with
+ [] -> ()
+ | [a1] ->
+ printf "("; print_struct_const a1; printf ")"
+ | a1::al ->
+ printf "("; print_struct_const a1;
+ List.iter (fun a -> printf ", "; print_struct_const a) al;
+ printf ")"
+ end
+ | Const_float_array a ->
+ printf "[|";
+ List.iter (fun f -> print_float f; printf "; ") a;
+ printf "|]"
+
+(* Print an obj *)
+
+let same_custom x y =
+ Obj.field x 0 = Obj.field (Obj.repr y) 0
+
+let rec print_obj x =
+ if Obj.is_block x then begin
+ let tag = Obj.tag x in
+ if tag = Obj.string_tag then
+ printf "%S" (Obj.magic x : string)
+ else if tag = Obj.double_tag then
+ printf "%.12g" (Obj.magic x : float)
+ else if tag = Obj.double_array_tag then begin
+ let a = (Obj.magic x : float array) in
+ printf "[|";
+ for i = 0 to Array.length a - 1 do
+ if i > 0 then printf ", ";
+ printf "%.12g" a.(i)
+ done;
+ printf "|]"
+ end else if tag = Obj.custom_tag && same_custom x 0l then
+ printf "%ldl" (Obj.magic x : int32)
+ else if tag = Obj.custom_tag && same_custom x 0n then
+ printf "%ndn" (Obj.magic x : nativeint)
+ else if tag = Obj.custom_tag && same_custom x 0L then
+ printf "%LdL" (Obj.magic x : int64)
+ else if tag < Obj.no_scan_tag then begin
+ printf "<%d>" (Obj.tag x);
+ match Obj.size x with
+ 0 -> ()
+ | 1 ->
+ printf "("; print_obj (Obj.field x 0); printf ")"
+ | n ->
+ printf "("; print_obj (Obj.field x 0);
+ for i = 1 to n - 1 do
+ printf ", "; print_obj (Obj.field x i)
+ done;
+ printf ")"
+ end else
+ printf "<tag %d>" tag
+ end else
+ printf "%d" (Obj.magic x : int)
+
+(* Current position in input file *)
+
+let currpos ic =
+ pos_in ic - !start
+
+(* Access in the relocation table *)
+
+let rec rassoc key = function
+ [] -> raise Not_found
+ | (a,b) :: l -> if b = key then a else rassoc key l
+
+let find_reloc ic =
+ rassoc (pos_in ic - !start) !reloc
+
+(* Symbolic printing of global names, etc *)
+
+let print_getglobal_name ic =
+ if !objfile then begin
+ begin try
+ match find_reloc ic with
+ Reloc_getglobal id -> print_string (Ident.name id)
+ | Reloc_literal sc -> print_struct_const sc
+ | _ -> print_string "<wrong reloc>"
+ with Not_found ->
+ print_string "<no reloc>"
+ end;
+ ignore (inputu ic);
+ end
+ else begin
+ let n = inputu ic in
+ if n >= Array.length !globals || n < 0
+ then print_string "<global table overflow>"
+ else match !globals.(n) with
+ Global id -> print_string(Ident.name id)
+ | Constant obj -> print_obj obj
+ | _ -> print_string "???"
+ end
+
+let print_setglobal_name ic =
+ if !objfile then begin
+ begin try
+ match find_reloc ic with
+ Reloc_setglobal id -> print_string (Ident.name id)
+ | _ -> print_string "<wrong reloc>"
+ with Not_found ->
+ print_string "<no reloc>"
+ end;
+ ignore (inputu ic);
+ end
+ else begin
+ let n = inputu ic in
+ if n >= Array.length !globals || n < 0
+ then print_string "<global table overflow>"
+ else match !globals.(n) with
+ Global id -> print_string(Ident.name id)
+ | _ -> print_string "???"
+ end
+
+let print_primitive ic =
+ if !objfile then begin
+ begin try
+ match find_reloc ic with
+ Reloc_primitive s -> print_string s
+ | _ -> print_string "<wrong reloc>"
+ with Not_found ->
+ print_string "<no reloc>"
+ end;
+ ignore (inputu ic);
+ end
+ else begin
+ let n = inputu ic in
+ if n >= Array.length !primitives || n < 0
+ then print_int n
+ else print_string !primitives.(n)
+ end
+
+(* Disassemble one instruction *)
+
+let currpc ic =
+ currpos ic / 4
+
+type shape =
+ | Nothing
+ | Uint
+ | Sint
+ | Uint_Uint
+ | Disp
+ | Uint_Disp
+ | Sint_Disp
+ | Getglobal
+ | Getglobal_Uint
+ | Setglobal
+ | Primitive
+ | Uint_Primitive
+ | Switch
+ | Closurerec
+ | Pubmet
+;;
+
+let op_shapes = [
+ opACC0, Nothing;
+ opACC1, Nothing;
+ opACC2, Nothing;
+ opACC3, Nothing;
+ opACC4, Nothing;
+ opACC5, Nothing;
+ opACC6, Nothing;
+ opACC7, Nothing;
+ opACC, Uint;
+ opPUSH, Nothing;
+ opPUSHACC0, Nothing;
+ opPUSHACC1, Nothing;
+ opPUSHACC2, Nothing;
+ opPUSHACC3, Nothing;
+ opPUSHACC4, Nothing;
+ opPUSHACC5, Nothing;
+ opPUSHACC6, Nothing;
+ opPUSHACC7, Nothing;
+ opPUSHACC, Uint;
+ opPOP, Uint;
+ opASSIGN, Uint;
+ opENVACC1, Nothing;
+ opENVACC2, Nothing;
+ opENVACC3, Nothing;
+ opENVACC4, Nothing;
+ opENVACC, Uint;
+ opPUSHENVACC1, Nothing;
+ opPUSHENVACC2, Nothing;
+ opPUSHENVACC3, Nothing;
+ opPUSHENVACC4, Nothing;
+ opPUSHENVACC, Uint;
+ opPUSH_RETADDR, Disp;
+ opAPPLY, Uint;
+ opAPPLY1, Nothing;
+ opAPPLY2, Nothing;
+ opAPPLY3, Nothing;
+ opAPPTERM, Uint_Uint;
+ opAPPTERM1, Uint;
+ opAPPTERM2, Uint;
+ opAPPTERM3, Uint;
+ opRETURN, Uint;
+ opRESTART, Nothing;
+ opGRAB, Uint;
+ opCLOSURE, Uint_Disp;
+ opCLOSUREREC, Closurerec;
+ opOFFSETCLOSUREM2, Nothing;
+ opOFFSETCLOSURE0, Nothing;
+ opOFFSETCLOSURE2, Nothing;
+ opOFFSETCLOSURE, Sint; (* was Uint *)
+ opPUSHOFFSETCLOSUREM2, Nothing;
+ opPUSHOFFSETCLOSURE0, Nothing;
+ opPUSHOFFSETCLOSURE2, Nothing;
+ opPUSHOFFSETCLOSURE, Sint; (* was Nothing *)
+ opGETGLOBAL, Getglobal;
+ opPUSHGETGLOBAL, Getglobal;
+ opGETGLOBALFIELD, Getglobal_Uint;
+ opPUSHGETGLOBALFIELD, Getglobal_Uint;
+ opSETGLOBAL, Setglobal;
+ opATOM0, Nothing;
+ opATOM, Uint;
+ opPUSHATOM0, Nothing;
+ opPUSHATOM, Uint;
+ opMAKEBLOCK, Uint_Uint;
+ opMAKEBLOCK1, Uint;
+ opMAKEBLOCK2, Uint;
+ opMAKEBLOCK3, Uint;
+ opMAKEFLOATBLOCK, Uint;
+ opGETFIELD0, Nothing;
+ opGETFIELD1, Nothing;
+ opGETFIELD2, Nothing;
+ opGETFIELD3, Nothing;
+ opGETFIELD, Uint;
+ opGETFLOATFIELD, Uint;
+ opSETFIELD0, Nothing;
+ opSETFIELD1, Nothing;
+ opSETFIELD2, Nothing;
+ opSETFIELD3, Nothing;
+ opSETFIELD, Uint;
+ opSETFLOATFIELD, Uint;
+ opVECTLENGTH, Nothing;
+ opGETVECTITEM, Nothing;
+ opSETVECTITEM, Nothing;
+ opGETSTRINGCHAR, Nothing;
+ opSETSTRINGCHAR, Nothing;
+ opBRANCH, Disp;
+ opBRANCHIF, Disp;
+ opBRANCHIFNOT, Disp;
+ opSWITCH, Switch;
+ opBOOLNOT, Nothing;
+ opPUSHTRAP, Disp;
+ opPOPTRAP, Nothing;
+ opRAISE, Nothing;
+ opCHECK_SIGNALS, Nothing;
+ opC_CALL1, Primitive;
+ opC_CALL2, Primitive;
+ opC_CALL3, Primitive;
+ opC_CALL4, Primitive;
+ opC_CALL5, Primitive;
+ opC_CALLN, Uint_Primitive;
+ opCONST0, Nothing;
+ opCONST1, Nothing;
+ opCONST2, Nothing;
+ opCONST3, Nothing;
+ opCONSTINT, Sint;
+ opPUSHCONST0, Nothing;
+ opPUSHCONST1, Nothing;
+ opPUSHCONST2, Nothing;
+ opPUSHCONST3, Nothing;
+ opPUSHCONSTINT, Sint;
+ opNEGINT, Nothing;
+ opADDINT, Nothing;
+ opSUBINT, Nothing;
+ opMULINT, Nothing;
+ opDIVINT, Nothing;
+ opMODINT, Nothing;
+ opANDINT, Nothing;
+ opORINT, Nothing;
+ opXORINT, Nothing;
+ opLSLINT, Nothing;
+ opLSRINT, Nothing;
+ opASRINT, Nothing;
+ opEQ, Nothing;
+ opNEQ, Nothing;
+ opLTINT, Nothing;
+ opLEINT, Nothing;
+ opGTINT, Nothing;
+ opGEINT, Nothing;
+ opOFFSETINT, Sint;
+ opOFFSETREF, Sint;
+ opISINT, Nothing;
+ opGETMETHOD, Nothing;
+ opGETDYNMET, Nothing;
+ opGETPUBMET, Pubmet;
+ opBEQ, Sint_Disp;
+ opBNEQ, Sint_Disp;
+ opBLTINT, Sint_Disp;
+ opBLEINT, Sint_Disp;
+ opBGTINT, Sint_Disp;
+ opBGEINT, Sint_Disp;
+ opULTINT, Nothing;
+ opUGEINT, Nothing;
+ opBULTINT, Uint_Disp;
+ opBUGEINT, Uint_Disp;
+ opSTOP, Nothing;
+ opEVENT, Nothing;
+ opBREAK, Nothing;
+];;
+
+let print_event ev =
+ let ls = ev.ev_loc.loc_start in
+ let le = ev.ev_loc.loc_end in
+ printf "File \"%s\", line %d, characters %d-%d:\n" ls.Lexing.pos_fname
+ ls.Lexing.pos_lnum (ls.Lexing.pos_cnum - ls.Lexing.pos_bol)
+ (le.Lexing.pos_cnum - ls.Lexing.pos_bol)
+
+let print_instr ic =
+ let pos = currpos ic in
+ List.iter print_event (Hashtbl.find_all event_table pos);
+ printf "%8d " (pos / 4);
+ let op = inputu ic in
+ if op >= Array.length names_of_instructions || op < 0
+ then (print_string "*** unknown opcode : "; print_int op)
+ else print_string names_of_instructions.(op);
+ print_string " ";
+ begin try match List.assoc op op_shapes with
+ | Uint -> print_int (inputu ic)
+ | Sint -> print_int (inputs ic)
+ | Uint_Uint
+ -> print_int (inputu ic); print_string ", "; print_int (inputu ic)
+ | Disp -> let p = currpc ic in print_int (p + inputs ic)
+ | Uint_Disp
+ -> print_int (inputu ic); print_string ", ";
+ let p = currpc ic in print_int (p + inputs ic)
+ | Sint_Disp
+ -> print_int (inputs ic); print_string ", ";
+ let p = currpc ic in print_int (p + inputs ic)
+ | Getglobal -> print_getglobal_name ic
+ | Getglobal_Uint
+ -> print_getglobal_name ic; print_string ", "; print_int (inputu ic)
+ | Setglobal -> print_setglobal_name ic
+ | Primitive -> print_primitive ic
+ | Uint_Primitive
+ -> print_int(inputu ic); print_string ", "; print_primitive ic
+ | Switch
+ -> let n = inputu ic in
+ let orig = currpc ic in
+ for i = 0 to (n land 0xFFFF) - 1 do
+ print_string "\n int "; print_int i; print_string " -> ";
+ print_int(orig + inputs ic);
+ done;
+ for i = 0 to (n lsr 16) - 1 do
+ print_string "\n tag "; print_int i; print_string " -> ";
+ print_int(orig + inputs ic);
+ done;
+ | Closurerec
+ -> let nfuncs = inputu ic in
+ let nvars = inputu ic in
+ let orig = currpc ic in
+ print_int nvars;
+ for i = 0 to nfuncs - 1 do
+ print_string ", ";
+ print_int (orig + inputs ic);
+ done;
+ | Pubmet
+ -> let tag = inputs ic in
+ let _cache = inputu ic in
+ print_int tag
+ | Nothing -> ()
+ with Not_found -> print_string "(unknown arguments)"
+ end;
+ print_string "\n";
+;;
+
+(* Disassemble a block of code *)
+
+let print_code ic len =
+ start := pos_in ic;
+ let stop = !start + len in
+ while pos_in ic < stop do print_instr ic done
+
+(* Dump relocation info *)
+
+let print_reloc (info, pos) =
+ printf " %d (%d) " pos (pos/4);
+ match info with
+ Reloc_literal sc -> print_struct_const sc; printf "\n"
+ | Reloc_getglobal id -> printf "require %s\n" (Ident.name id)
+ | Reloc_setglobal id -> printf "provide %s\n" (Ident.name id)
+ | Reloc_primitive s -> printf "prim %s\n" s
+
+(* Print a .cmo file *)
+
+let dump_obj filename ic =
+ let buffer = String.create (String.length cmo_magic_number) in
+ really_input ic buffer 0 (String.length cmo_magic_number);
+ if buffer <> cmo_magic_number then begin
+ prerr_endline "Not an object file"; exit 2
+ end;
+ let cu_pos = input_binary_int ic in
+ seek_in ic cu_pos;
+ let cu = (input_value ic : compilation_unit) in
+ reloc := cu.cu_reloc;
+ if cu.cu_debug > 0 then begin
+ seek_in ic cu.cu_debug;
+ let evl = (input_value ic : debug_event list) in
+ record_events 0 evl
+ end;
+ seek_in ic cu.cu_pos;
+ print_code ic cu.cu_codesize
+
+(* Read the primitive table from an executable *)
+
+let read_primitive_table ic len =
+ let p = String.create len in
+ really_input ic p 0 len;
+ let rec split beg cur =
+ if cur >= len then []
+ else if p.[cur] = '\000' then
+ String.sub p beg (cur - beg) :: split (cur + 1) (cur + 1)
+ else
+ split beg (cur + 1) in
+ Array.of_list(split 0 0)
+
+(* Print an executable file *)
+
+let dump_exe ic =
+ Bytesections.read_toc ic;
+ let prim_size = Bytesections.seek_section ic "PRIM" in
+ primitives := read_primitive_table ic prim_size;
+ ignore(Bytesections.seek_section ic "DATA");
+ let init_data = (input_value ic : Obj.t array) in
+ globals := Array.create (Array.length init_data) Empty;
+ for i = 0 to Array.length init_data - 1 do
+ !globals.(i) <- Constant (init_data.(i))
+ done;
+ ignore(Bytesections.seek_section ic "SYMB");
+ let (_, sym_table) = (input_value ic : int * (Ident.t, int) Tbl.t) in
+ Tbl.iter (fun id pos -> !globals.(pos) <- Global id) sym_table;
+ begin try
+ ignore (Bytesections.seek_section ic "DBUG");
+ let num_eventlists = input_binary_int ic in
+ for i = 1 to num_eventlists do
+ let orig = input_binary_int ic in
+ let evl = (input_value ic : debug_event list) in
+ record_events orig evl
+ done
+ with Not_found -> ()
+ end;
+ let code_size = Bytesections.seek_section ic "CODE" in
+ print_code ic code_size
+
+let main() =
+ for i = 1 to Array.length Sys.argv - 1 do
+ let filnam = Sys.argv.(i) in
+ let ic = open_in_bin filnam in
+ if i>1 then print_newline ();
+ printf "## start of ocaml dump of %S\n%!" filnam;
+ begin try
+ objfile := false; dump_exe ic
+ with Bytesections.Bad_magic_number ->
+ objfile := true; seek_in ic 0; dump_obj (Sys.argv.(i)) ic
+ end;
+ close_in ic;
+ printf "## end of ocaml dump of %S\n%!" filnam;
+ done;
+ exit 0
+
+let _ = main ()
diff --git a/ocaml-binary-annot/tools/lexer299.mll b/ocaml-binary-annot/tools/lexer299.mll
new file mode 100644
index 0000000000..9a244721df
--- /dev/null
+++ b/ocaml-binary-annot/tools/lexer299.mll
@@ -0,0 +1,460 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* The lexer definition *)
+
+{
+open Lexing
+open Misc
+
+type token =
+ AMPERAMPER
+ | AMPERSAND
+ | AND
+ | AS
+ | ASSERT
+ | BACKQUOTE
+ | BAR
+ | BARBAR
+ | BARRBRACKET
+ | BEGIN
+ | CHAR of (char)
+ | CLASS
+ | COLON
+ | COLONCOLON
+ | COLONEQUAL
+ | COLONGREATER
+ | COMMA
+ | CONSTRAINT
+ | DO
+ | DONE
+ | DOT
+ | DOTDOT
+ | DOWNTO
+ | ELSE
+ | END
+ | EOF
+ | EQUAL
+ | EXCEPTION
+ | EXTERNAL
+ | FALSE
+ | FLOAT of (string)
+ | FOR
+ | FUN
+ | FUNCTION
+ | FUNCTOR
+ | GREATER
+ | GREATERRBRACE
+ | GREATERRBRACKET
+ | IF
+ | IN
+ | INCLUDE
+ | INFIXOP0 of (string)
+ | INFIXOP1 of (string)
+ | INFIXOP2 of (string)
+ | INFIXOP3 of (string)
+ | INFIXOP4 of (string)
+ | INHERIT
+ | INITIALIZER
+ | INT of (int)
+ | LABEL of (string)
+ | LABELID of (string)
+ | LAZY
+ | LBRACE
+ | LBRACELESS
+ | LBRACKET
+ | LBRACKETBAR
+ | LBRACKETLESS
+ | LESS
+ | LESSMINUS
+ | LET
+ | LIDENT of (string)
+ | LPAREN
+ | MATCH
+ | METHOD
+ | MINUSGREATER
+ | MODULE
+ | MUTABLE
+ | NEW
+ | OBJECT
+ | OF
+ | OPEN
+ | OR
+ | PARSER
+ | PREFIXOP of (string)
+ | PRIVATE
+ | QUESTION
+ | QUESTION2
+ | QUOTE
+ | RBRACE
+ | RBRACKET
+ | REC
+ | RPAREN
+ | SEMI
+ | SEMISEMI
+ | SHARP
+ | SIG
+ | STAR
+ | STRING of (string)
+ | STRUCT
+ | SUBTRACTIVE of (string)
+ | THEN
+ | TO
+ | TRUE
+ | TRY
+ | TYPE
+ | UIDENT of (string)
+ | UNDERSCORE
+ | VAL
+ | VIRTUAL
+ | WHEN
+ | WHILE
+ | WITH
+
+type error =
+ | Illegal_character of char
+ | Unterminated_comment
+ | Unterminated_string
+ | Unterminated_string_in_comment
+;;
+
+exception Error of error * int * int
+
+(* The table of keywords *)
+
+let keyword_table =
+ create_hashtable 149 [
+ "and", AND;
+ "as", AS;
+ "assert", ASSERT;
+ "begin", BEGIN;
+ "class", CLASS;
+ "constraint", CONSTRAINT;
+ "do", DO;
+ "done", DONE;
+ "downto", DOWNTO;
+ "else", ELSE;
+ "end", END;
+ "exception", EXCEPTION;
+ "external", EXTERNAL;
+ "false", FALSE;
+ "for", FOR;
+ "fun", FUN;
+ "function", FUNCTION;
+ "functor", FUNCTOR;
+ "if", IF;
+ "in", IN;
+ "include", INCLUDE;
+ "inherit", INHERIT;
+ "initializer", INITIALIZER;
+ "lazy", LAZY;
+ "let", LET;
+ "match", MATCH;
+ "method", METHOD;
+ "module", MODULE;
+ "mutable", MUTABLE;
+ "new", NEW;
+ "object", OBJECT;
+ "of", OF;
+ "open", OPEN;
+ "or", OR;
+ "parser", PARSER;
+ "private", PRIVATE;
+ "rec", REC;
+ "sig", SIG;
+ "struct", STRUCT;
+ "then", THEN;
+ "to", TO;
+ "true", TRUE;
+ "try", TRY;
+ "type", TYPE;
+ "val", VAL;
+ "virtual", VIRTUAL;
+ "when", WHEN;
+ "while", WHILE;
+ "with", WITH;
+
+ "mod", INFIXOP3("mod");
+ "land", INFIXOP3("land");
+ "lor", INFIXOP3("lor");
+ "lxor", INFIXOP3("lxor");
+ "lsl", INFIXOP4("lsl");
+ "lsr", INFIXOP4("lsr");
+ "asr", INFIXOP4("asr")
+]
+
+(* To buffer string literals *)
+
+let initial_string_buffer = String.create 256
+let string_buff = ref initial_string_buffer
+let string_index = ref 0
+
+let reset_string_buffer () =
+ string_buff := initial_string_buffer;
+ string_index := 0
+
+let store_string_char c =
+ if !string_index >= String.length (!string_buff) then begin
+ let new_buff = String.create (String.length (!string_buff) * 2) in
+ String.blit (!string_buff) 0 new_buff 0 (String.length (!string_buff));
+ string_buff := new_buff
+ end;
+ String.unsafe_set (!string_buff) (!string_index) c;
+ incr string_index
+
+let get_stored_string () =
+ let s = String.sub (!string_buff) 0 (!string_index) in
+ string_buff := initial_string_buffer;
+ s
+
+(* To translate escape sequences *)
+
+let char_for_backslash = function
+ | 'n' -> '\010'
+ | 'r' -> '\013'
+ | 'b' -> '\008'
+ | 't' -> '\009'
+ | c -> c
+
+let char_for_decimal_code lexbuf i =
+ let c = 100 * (Char.code(Lexing.lexeme_char lexbuf i) - 48) +
+ 10 * (Char.code(Lexing.lexeme_char lexbuf (i+1)) - 48) +
+ (Char.code(Lexing.lexeme_char lexbuf (i+2)) - 48) in
+ Char.chr(c land 0xFF)
+
+(* To store the position of the beginning of a string and comment *)
+let string_start_pos = ref 0;;
+let comment_start_pos = ref [];;
+
+(* Error report *)
+
+open Format
+
+let report_error ppf = function
+ | Illegal_character c ->
+ fprintf ppf "Illegal character (%s)" (Char.escaped c)
+ | Unterminated_comment ->
+ fprintf ppf "Comment not terminated"
+ | Unterminated_string ->
+ fprintf ppf "String literal not terminated"
+ | Unterminated_string_in_comment ->
+ fprintf ppf "This comment contains an unterminated string literal"
+;;
+
+}
+
+let blank = [' ' '\010' '\013' '\009' '\012']
+let lowercase = ['a'-'z' '\223'-'\246' '\248'-'\255' '_']
+let uppercase = ['A'-'Z' '\192'-'\214' '\216'-'\222']
+let identchar =
+ ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9']
+let symbolchar =
+ ['!' '$' '%' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~']
+let symbolchar2 =
+ ['!' '$' '%' '&' '*' '+' '-' '.' '/' '<' '=' '>' '?' '@' '^' '|' '~']
+(* ['!' '$' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~'] *)
+let decimal_literal = ['0'-'9']+
+let hex_literal = '0' ['x' 'X'] ['0'-'9' 'A'-'F' 'a'-'f']+
+let oct_literal = '0' ['o' 'O'] ['0'-'7']+
+let bin_literal = '0' ['b' 'B'] ['0'-'1']+
+let float_literal =
+ ['0'-'9']+ ('.' ['0'-'9']* )? (['e' 'E'] ['+' '-']? ['0'-'9']+)?
+
+rule token = parse
+ blank +
+ { token lexbuf }
+ | "_"
+ { UNDERSCORE }
+ | lowercase identchar * ':' [ ^ ':' '=' '>']
+ { let s = Lexing.lexeme lexbuf in
+ lexbuf.lex_curr_pos <- lexbuf.lex_curr_pos - 1;
+ lexbuf.lex_curr_p <-
+ {lexbuf.lex_curr_p with pos_cnum = lexbuf.lex_curr_p.pos_cnum - 1};
+ LABEL (String.sub s 0 (String.length s - 2)) }
+(*
+ | lowercase identchar * ':'
+ { let s = Lexing.lexeme lexbuf in
+ LABEL (String.sub s 0 (String.length s - 1)) }
+ | '%' lowercase identchar *
+*)
+ | ':' lowercase identchar *
+ { let s = Lexing.lexeme lexbuf in
+ let l = String.length s - 1 in
+ LABELID (String.sub s 1 l) }
+ | lowercase identchar *
+ { let s = Lexing.lexeme lexbuf in
+ try
+ Hashtbl.find keyword_table s
+ with Not_found ->
+ LIDENT s }
+ | uppercase identchar *
+ { UIDENT(Lexing.lexeme lexbuf) } (* No capitalized keywords *)
+ | decimal_literal | hex_literal | oct_literal | bin_literal
+ { INT (int_of_string(Lexing.lexeme lexbuf)) }
+ | float_literal
+ { FLOAT (Lexing.lexeme lexbuf) }
+ | "\""
+ { reset_string_buffer();
+ let string_start = Lexing.lexeme_start lexbuf in
+ string_start_pos := string_start;
+ string lexbuf;
+ lexbuf.Lexing.lex_start_pos <-
+ string_start - lexbuf.Lexing.lex_abs_pos;
+ STRING (get_stored_string()) }
+ | "'" [^ '\\' '\''] "'"
+ { CHAR(Lexing.lexeme_char lexbuf 1) }
+ | "'" '\\' ['\\' '\'' 'n' 't' 'b' 'r'] "'"
+ { CHAR(char_for_backslash (Lexing.lexeme_char lexbuf 2)) }
+ | "'" '\\' ['0'-'9'] ['0'-'9'] ['0'-'9'] "'"
+ { CHAR(char_for_decimal_code lexbuf 2) }
+ | "(*"
+ { comment_start_pos := [Lexing.lexeme_start lexbuf];
+ comment lexbuf;
+ token lexbuf }
+ | "(*)"
+ { let loc = { Location.loc_start = Lexing.lexeme_start_p lexbuf;
+ Location.loc_end = Lexing.lexeme_end_p lexbuf;
+ Location.loc_ghost = false }
+ in
+ Location.prerr_warning loc (Warnings.Comment_start);
+ comment_start_pos := [Lexing.lexeme_start lexbuf];
+ comment lexbuf;
+ token lexbuf
+ }
+ | "*)"
+ { let loc = { Location.loc_start = Lexing.lexeme_start_p lexbuf;
+ Location.loc_end = Lexing.lexeme_end_p lexbuf;
+ Location.loc_ghost = false }
+ in
+ Location.prerr_warning loc Warnings.Comment_not_end;
+ lexbuf.Lexing.lex_curr_pos <- lexbuf.Lexing.lex_curr_pos - 1;
+ STAR
+ }
+ | "#" [' ' '\t']* ['0'-'9']+ [^ '\n' '\r'] * ('\n' | '\r' | "\r\n")
+ (* # linenum ... *)
+ { token lexbuf }
+ | "#" { SHARP }
+ | "&" { AMPERSAND }
+ | "&&" { AMPERAMPER }
+ | "`" { BACKQUOTE }
+ | "'" { QUOTE }
+ | "(" { LPAREN }
+ | ")" { RPAREN }
+ | "*" { STAR }
+ | "," { COMMA }
+ | "?" { QUESTION }
+ | "??" { QUESTION2 }
+ | "->" { MINUSGREATER }
+ | "." { DOT }
+ | ".." { DOTDOT }
+ | ":" { COLON }
+ | "::" { COLONCOLON }
+ | ":=" { COLONEQUAL }
+ | ":>" { COLONGREATER }
+ | ";" { SEMI }
+ | ";;" { SEMISEMI }
+ | "<" { LESS }
+ | "<-" { LESSMINUS }
+ | "=" { EQUAL }
+ | "[" { LBRACKET }
+ | "[|" { LBRACKETBAR }
+ | "[<" { LBRACKETLESS }
+ | "]" { RBRACKET }
+ | "{" { LBRACE }
+ | "{<" { LBRACELESS }
+ | "|" { BAR }
+ | "||" { BARBAR }
+ | "|]" { BARRBRACKET }
+ | ">" { GREATER }
+ | ">]" { GREATERRBRACKET }
+ | "}" { RBRACE }
+ | ">}" { GREATERRBRACE }
+
+ | "!=" { INFIXOP0 "!=" }
+ | "-" { SUBTRACTIVE "-" }
+ | "-." { SUBTRACTIVE "-." }
+
+ | ['!' '~'] symbolchar *
+ { PREFIXOP(Lexing.lexeme lexbuf) }
+ | '?' symbolchar2 *
+ { PREFIXOP(Lexing.lexeme lexbuf) }
+ | ['=' '<' '>' '|' '&' '$'] symbolchar *
+ { INFIXOP0(Lexing.lexeme lexbuf) }
+ | ['@' '^'] symbolchar *
+ { INFIXOP1(Lexing.lexeme lexbuf) }
+ | ['+' '-'] symbolchar *
+ { INFIXOP2(Lexing.lexeme lexbuf) }
+ | "**" symbolchar *
+ { INFIXOP4(Lexing.lexeme lexbuf) }
+ | ['*' '/' '%'] symbolchar *
+ { INFIXOP3(Lexing.lexeme lexbuf) }
+ | eof { EOF }
+ | _
+ { raise (Error(Illegal_character ((Lexing.lexeme lexbuf).[0]),
+ Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) }
+
+and comment = parse
+ "(*"
+ { comment_start_pos := Lexing.lexeme_start lexbuf :: !comment_start_pos;
+ comment lexbuf;
+ }
+ | "*)"
+ { match !comment_start_pos with
+ | [] -> assert false
+ | [x] -> ()
+ | _ :: l -> comment_start_pos := l;
+ comment lexbuf;
+ }
+ | "\""
+ { reset_string_buffer();
+ string_start_pos := Lexing.lexeme_start lexbuf;
+ begin try string lexbuf
+ with Error (Unterminated_string, _, _) ->
+ let st = List.hd !comment_start_pos in
+ raise (Error (Unterminated_string_in_comment, st, st + 2))
+ end;
+ string_buff := initial_string_buffer;
+ comment lexbuf }
+ | "''"
+ { comment lexbuf }
+ | "'" [^ '\\' '\''] "'"
+ { comment lexbuf }
+ | "'\\" ['\\' '\'' 'n' 't' 'b' 'r'] "'"
+ { comment lexbuf }
+ | "'\\" ['0'-'9'] ['0'-'9'] ['0'-'9'] "'"
+ { comment lexbuf }
+ | eof
+ { let st = List.hd !comment_start_pos in
+ raise (Error (Unterminated_comment, st, st + 2));
+ }
+ | _
+ { comment lexbuf }
+
+and string = parse
+ '"'
+ { () }
+ | '\\' ("\010" | "\013" | "\013\010") [' ' '\009'] *
+ { string lexbuf }
+ | '\\' ['\\' '"' 'n' 't' 'b' 'r']
+ { store_string_char(char_for_backslash(Lexing.lexeme_char lexbuf 1));
+ string lexbuf }
+ | '\\' ['0'-'9'] ['0'-'9'] ['0'-'9']
+ { store_string_char(char_for_decimal_code lexbuf 1);
+ string lexbuf }
+ | eof
+ { raise (Error (Unterminated_string,
+ !string_start_pos, !string_start_pos+1)) }
+ | _
+ { store_string_char(Lexing.lexeme_char lexbuf 0);
+ string lexbuf }
diff --git a/ocaml-binary-annot/tools/lexer301.mll b/ocaml-binary-annot/tools/lexer301.mll
new file mode 100644
index 0000000000..daec549e7e
--- /dev/null
+++ b/ocaml-binary-annot/tools/lexer301.mll
@@ -0,0 +1,461 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* The lexer definition *)
+
+{
+open Misc
+
+type token =
+ AMPERAMPER
+ | AMPERSAND
+ | AND
+ | AS
+ | ASSERT
+ | BACKQUOTE
+ | BAR
+ | BARBAR
+ | BARRBRACKET
+ | BEGIN
+ | CHAR of (char)
+ | CLASS
+ | COLON
+ | COLONCOLON
+ | COLONEQUAL
+ | COLONGREATER
+ | COMMA
+ | CONSTRAINT
+ | DO
+ | DONE
+ | DOT
+ | DOTDOT
+ | DOWNTO
+ | ELSE
+ | END
+ | EOF
+ | EQUAL
+ | EXCEPTION
+ | EXTERNAL
+ | FALSE
+ | FLOAT of (string)
+ | FOR
+ | FUN
+ | FUNCTION
+ | FUNCTOR
+ | GREATER
+ | GREATERRBRACE
+ | GREATERRBRACKET
+ | IF
+ | IN
+ | INCLUDE
+ | INFIXOP0 of (string)
+ | INFIXOP1 of (string)
+ | INFIXOP2 of (string)
+ | INFIXOP3 of (string)
+ | INFIXOP4 of (string)
+ | INHERIT
+ | INITIALIZER
+ | INT of (int)
+ | LABEL of (string)
+ | LAZY
+ | LBRACE
+ | LBRACELESS
+ | LBRACKET
+ | LBRACKETBAR
+ | LBRACKETLESS
+ | LESS
+ | LESSMINUS
+ | LET
+ | LIDENT of (string)
+ | LPAREN
+ | MATCH
+ | METHOD
+ | MINUS
+ | MINUSDOT
+ | MINUSGREATER
+ | MODULE
+ | MUTABLE
+ | NEW
+ | OBJECT
+ | OF
+ | OPEN
+ | OPTLABEL of (string)
+ | OR
+ | PARSER
+ | PLUS
+ | PREFIXOP of (string)
+ | PRIVATE
+ | QUESTION
+ | QUESTION2
+ | QUOTE
+ | RBRACE
+ | RBRACKET
+ | REC
+ | RPAREN
+ | SEMI
+ | SEMISEMI
+ | SHARP
+ | SIG
+ | STAR
+ | STRING of (string)
+ | STRUCT
+ | THEN
+ | TILDE
+ | TO
+ | TRUE
+ | TRY
+ | TYPE
+ | UIDENT of (string)
+ | UNDERSCORE
+ | VAL
+ | VIRTUAL
+ | WHEN
+ | WHILE
+ | WITH
+
+type error =
+ | Illegal_character of char
+ | Unterminated_comment
+ | Unterminated_string
+ | Unterminated_string_in_comment
+ | Keyword_as_label of string
+;;
+
+exception Error of error * int * int
+
+(* The table of keywords *)
+
+let keyword_table =
+ create_hashtable 149 [
+ "and", AND;
+ "as", AS;
+ "assert", ASSERT;
+ "begin", BEGIN;
+ "class", CLASS;
+ "constraint", CONSTRAINT;
+ "do", DO;
+ "done", DONE;
+ "downto", DOWNTO;
+ "else", ELSE;
+ "end", END;
+ "exception", EXCEPTION;
+ "external", EXTERNAL;
+ "false", FALSE;
+ "for", FOR;
+ "fun", FUN;
+ "function", FUNCTION;
+ "functor", FUNCTOR;
+ "if", IF;
+ "in", IN;
+ "include", INCLUDE;
+ "inherit", INHERIT;
+ "initializer", INITIALIZER;
+ "lazy", LAZY;
+ "let", LET;
+ "match", MATCH;
+ "method", METHOD;
+ "module", MODULE;
+ "mutable", MUTABLE;
+ "new", NEW;
+ "object", OBJECT;
+ "of", OF;
+ "open", OPEN;
+ "or", OR;
+ "parser", PARSER;
+ "private", PRIVATE;
+ "rec", REC;
+ "sig", SIG;
+ "struct", STRUCT;
+ "then", THEN;
+ "to", TO;
+ "true", TRUE;
+ "try", TRY;
+ "type", TYPE;
+ "val", VAL;
+ "virtual", VIRTUAL;
+ "when", WHEN;
+ "while", WHILE;
+ "with", WITH;
+
+ "mod", INFIXOP3("mod");
+ "land", INFIXOP3("land");
+ "lor", INFIXOP3("lor");
+ "lxor", INFIXOP3("lxor");
+ "lsl", INFIXOP4("lsl");
+ "lsr", INFIXOP4("lsr");
+ "asr", INFIXOP4("asr")
+]
+
+(* To buffer string literals *)
+
+let initial_string_buffer = String.create 256
+let string_buff = ref initial_string_buffer
+let string_index = ref 0
+
+let reset_string_buffer () =
+ string_buff := initial_string_buffer;
+ string_index := 0
+
+let store_string_char c =
+ if !string_index >= String.length (!string_buff) then begin
+ let new_buff = String.create (String.length (!string_buff) * 2) in
+ String.blit (!string_buff) 0 new_buff 0 (String.length (!string_buff));
+ string_buff := new_buff
+ end;
+ String.unsafe_set (!string_buff) (!string_index) c;
+ incr string_index
+
+let get_stored_string () =
+ let s = String.sub (!string_buff) 0 (!string_index) in
+ string_buff := initial_string_buffer;
+ s
+
+(* To translate escape sequences *)
+
+let char_for_backslash = function
+ | 'n' -> '\010'
+ | 'r' -> '\013'
+ | 'b' -> '\008'
+ | 't' -> '\009'
+ | c -> c
+
+let char_for_decimal_code lexbuf i =
+ let c = 100 * (Char.code(Lexing.lexeme_char lexbuf i) - 48) +
+ 10 * (Char.code(Lexing.lexeme_char lexbuf (i+1)) - 48) +
+ (Char.code(Lexing.lexeme_char lexbuf (i+2)) - 48) in
+ Char.chr(c land 0xFF)
+
+(* To store the position of the beginning of a string and comment *)
+let string_start_pos = ref 0;;
+let comment_start_pos = ref [];;
+let in_comment () = !comment_start_pos <> [];;
+
+(* Error report *)
+
+open Format
+
+let report_error ppf = function
+ | Illegal_character c ->
+ fprintf ppf "Illegal character (%s)" (Char.escaped c)
+ | Unterminated_comment ->
+ fprintf ppf "Comment not terminated"
+ | Unterminated_string ->
+ fprintf ppf "String literal not terminated"
+ | Unterminated_string_in_comment ->
+ fprintf ppf "This comment contains an unterminated string literal"
+ | Keyword_as_label kwd ->
+ fprintf ppf "`%s' is a keyword, it cannot be used as label name" kwd
+;;
+
+}
+
+let blank = [' ' '\010' '\013' '\009' '\012']
+let lowercase = ['a'-'z' '\223'-'\246' '\248'-'\255' '_']
+let uppercase = ['A'-'Z' '\192'-'\214' '\216'-'\222']
+let identchar =
+ ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9']
+let symbolchar =
+ ['!' '$' '%' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~']
+let decimal_literal = ['0'-'9']+
+let hex_literal = '0' ['x' 'X'] ['0'-'9' 'A'-'F' 'a'-'f']+
+let oct_literal = '0' ['o' 'O'] ['0'-'7']+
+let bin_literal = '0' ['b' 'B'] ['0'-'1']+
+let float_literal =
+ ['0'-'9']+ ('.' ['0'-'9']* )? (['e' 'E'] ['+' '-']? ['0'-'9']+)?
+
+rule token = parse
+ blank +
+ { token lexbuf }
+ | "_"
+ { UNDERSCORE }
+ | "~" { TILDE }
+ | "~" lowercase identchar * ':'
+ { let s = Lexing.lexeme lexbuf in
+ let name = String.sub s 1 (String.length s - 2) in
+ if Hashtbl.mem keyword_table name then
+ raise (Error(Keyword_as_label name, Lexing.lexeme_start lexbuf,
+ Lexing.lexeme_end lexbuf));
+ LABEL name }
+ | "?" { QUESTION }
+ | "?" lowercase identchar * ':'
+ { let s = Lexing.lexeme lexbuf in
+ let name = String.sub s 1 (String.length s - 2) in
+ if Hashtbl.mem keyword_table name then
+ raise (Error(Keyword_as_label name, Lexing.lexeme_start lexbuf,
+ Lexing.lexeme_end lexbuf));
+ OPTLABEL name }
+ | lowercase identchar *
+ { let s = Lexing.lexeme lexbuf in
+ try
+ Hashtbl.find keyword_table s
+ with Not_found ->
+ LIDENT s }
+ | uppercase identchar *
+ { UIDENT(Lexing.lexeme lexbuf) } (* No capitalized keywords *)
+ | decimal_literal | hex_literal | oct_literal | bin_literal
+ { INT (int_of_string(Lexing.lexeme lexbuf)) }
+ | float_literal
+ { FLOAT (Lexing.lexeme lexbuf) }
+ | "\""
+ { reset_string_buffer();
+ let string_start = Lexing.lexeme_start lexbuf in
+ string_start_pos := string_start;
+ string lexbuf;
+ lexbuf.Lexing.lex_start_pos <-
+ string_start - lexbuf.Lexing.lex_abs_pos;
+ STRING (get_stored_string()) }
+ | "'" [^ '\\' '\''] "'"
+ { CHAR(Lexing.lexeme_char lexbuf 1) }
+ | "'" '\\' ['\\' '\'' 'n' 't' 'b' 'r'] "'"
+ { CHAR(char_for_backslash (Lexing.lexeme_char lexbuf 2)) }
+ | "'" '\\' ['0'-'9'] ['0'-'9'] ['0'-'9'] "'"
+ { CHAR(char_for_decimal_code lexbuf 2) }
+ | "(*"
+ { comment_start_pos := [Lexing.lexeme_start lexbuf];
+ comment lexbuf;
+ token lexbuf }
+ | "(*)"
+ { let loc = Location.curr lexbuf
+ and warn = Warnings.Comment_start
+ in
+ Location.prerr_warning loc warn;
+ comment_start_pos := [Lexing.lexeme_start lexbuf];
+ comment lexbuf;
+ token lexbuf
+ }
+ | "*)"
+ { let loc = Location.curr lexbuf
+ and warn = Warnings.Comment_not_end
+ in
+ Location.prerr_warning loc warn;
+ lexbuf.Lexing.lex_curr_pos <- lexbuf.Lexing.lex_curr_pos - 1;
+ STAR
+ }
+ | "#" [' ' '\t']* ['0'-'9']+ [^ '\n' '\r'] * ('\n' | '\r' | "\r\n")
+ (* # linenum ... *)
+ { token lexbuf }
+ | "#" { SHARP }
+ | "&" { AMPERSAND }
+ | "&&" { AMPERAMPER }
+ | "`" { BACKQUOTE }
+ | "'" { QUOTE }
+ | "(" { LPAREN }
+ | ")" { RPAREN }
+ | "*" { STAR }
+ | "," { COMMA }
+ | "??" { QUESTION2 }
+ | "->" { MINUSGREATER }
+ | "." { DOT }
+ | ".." { DOTDOT }
+ | ":" { COLON }
+ | "::" { COLONCOLON }
+ | ":=" { COLONEQUAL }
+ | ":>" { COLONGREATER }
+ | ";" { SEMI }
+ | ";;" { SEMISEMI }
+ | "<" { LESS }
+ | "<-" { LESSMINUS }
+ | "=" { EQUAL }
+ | "[" { LBRACKET }
+ | "[|" { LBRACKETBAR }
+ | "[<" { LBRACKETLESS }
+ | "]" { RBRACKET }
+ | "{" { LBRACE }
+ | "{<" { LBRACELESS }
+ | "|" { BAR }
+ | "||" { BARBAR }
+ | "|]" { BARRBRACKET }
+ | ">" { GREATER }
+ | ">]" { GREATERRBRACKET }
+ | "}" { RBRACE }
+ | ">}" { GREATERRBRACE }
+
+ | "!=" { INFIXOP0 "!=" }
+ | "+" { PLUS }
+ | "-" { MINUS }
+ | "-." { MINUSDOT }
+
+ | "!" symbolchar *
+ { PREFIXOP(Lexing.lexeme lexbuf) }
+ | ['~' '?'] symbolchar +
+ { PREFIXOP(Lexing.lexeme lexbuf) }
+ | ['=' '<' '>' '|' '&' '$'] symbolchar *
+ { INFIXOP0(Lexing.lexeme lexbuf) }
+ | ['@' '^'] symbolchar *
+ { INFIXOP1(Lexing.lexeme lexbuf) }
+ | ['+' '-'] symbolchar *
+ { INFIXOP2(Lexing.lexeme lexbuf) }
+ | "**" symbolchar *
+ { INFIXOP4(Lexing.lexeme lexbuf) }
+ | ['*' '/' '%'] symbolchar *
+ { INFIXOP3(Lexing.lexeme lexbuf) }
+ | eof { EOF }
+ | _
+ { raise (Error(Illegal_character ((Lexing.lexeme lexbuf).[0]),
+ Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) }
+
+and comment = parse
+ "(*"
+ { comment_start_pos := Lexing.lexeme_start lexbuf :: !comment_start_pos;
+ comment lexbuf;
+ }
+ | "*)"
+ { match !comment_start_pos with
+ | [] -> assert false
+ | [x] -> comment_start_pos := [];
+ | _ :: l -> comment_start_pos := l;
+ comment lexbuf;
+ }
+ | "\""
+ { reset_string_buffer();
+ string_start_pos := Lexing.lexeme_start lexbuf;
+ begin try string lexbuf
+ with Error (Unterminated_string, _, _) ->
+ let st = List.hd !comment_start_pos in
+ raise (Error (Unterminated_string_in_comment, st, st + 2))
+ end;
+ string_buff := initial_string_buffer;
+ comment lexbuf }
+ | "''"
+ { comment lexbuf }
+ | "'" [^ '\\' '\''] "'"
+ { comment lexbuf }
+ | "'\\" ['\\' '\'' 'n' 't' 'b' 'r'] "'"
+ { comment lexbuf }
+ | "'\\" ['0'-'9'] ['0'-'9'] ['0'-'9'] "'"
+ { comment lexbuf }
+ | eof
+ { let st = List.hd !comment_start_pos in
+ raise (Error (Unterminated_comment, st, st + 2));
+ }
+ | _
+ { comment lexbuf }
+
+and string = parse
+ '"'
+ { () }
+ | '\\' ("\010" | "\013" | "\013\010") [' ' '\009'] *
+ { string lexbuf }
+ | '\\' ['\\' '"' 'n' 't' 'b' 'r']
+ { store_string_char(char_for_backslash(Lexing.lexeme_char lexbuf 1));
+ string lexbuf }
+ | '\\' ['0'-'9'] ['0'-'9'] ['0'-'9']
+ { store_string_char(char_for_decimal_code lexbuf 1);
+ string lexbuf }
+ | eof
+ { raise (Error (Unterminated_string,
+ !string_start_pos, !string_start_pos+1)) }
+ | _
+ { store_string_char(Lexing.lexeme_char lexbuf 0);
+ string lexbuf }
diff --git a/ocaml-binary-annot/tools/magic b/ocaml-binary-annot/tools/magic
new file mode 100644
index 0000000000..7468066e01
--- /dev/null
+++ b/ocaml-binary-annot/tools/magic
@@ -0,0 +1,11 @@
+# Here are some definitions that can be added to the /usr/share/magic
+# database so that the file(1) command recognizes OCaml compiled files.
+# Contributed by Sven Luther.
+0 string Caml1999 Objective Caml
+>8 string X bytecode executable
+>8 string I interface data (.cmi)
+>8 string O bytecode object data (.cmo)
+>8 string A bytecode library data (.cma)
+>8 string Y native object data (.cmx)
+>8 string Z native library data (.cmxa)
+>9 string >\0 (Version %3.3s).
diff --git a/ocaml-binary-annot/tools/make-opcodes b/ocaml-binary-annot/tools/make-opcodes
new file mode 100644
index 0000000000..c8f573c682
--- /dev/null
+++ b/ocaml-binary-annot/tools/make-opcodes
@@ -0,0 +1,2 @@
+$1=="enum" {n=0; next; }
+ {for (i = 1; i <= NF; i++) {printf("let op%s = %d\n", $i, n++);}}
diff --git a/ocaml-binary-annot/tools/make-package-macosx b/ocaml-binary-annot/tools/make-package-macosx
new file mode 100755
index 0000000000..ebdf0eba2c
--- /dev/null
+++ b/ocaml-binary-annot/tools/make-package-macosx
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Damien Doligez, projet Moscova, INRIA Rocquencourt #
+# #
+# Copyright 2003 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+cd package-macosx
+rm -rf ocaml.pkg ocaml-rw.dmg
+
+VERSION=`sed -e 1q ../VERSION`
+VERSION_MAJOR=`sed -n -e '1s/^\([0-9]*\)\..*/\1/p' ../VERSION`
+VERSION_MINOR=`sed -n -e '1s/^[0-9]*\.\([0-9]*\)[.+].*/\1/p' ../VERSION`
+
+cat >Description.plist <<EOF
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+ <plist version="1.0">
+ <dict>
+ <key>IFPkgDescriptionDeleteWarning</key>
+ <string></string>
+ <key>IFPkgDescriptionDescription</key>
+ <string>The Objective Caml compiler and tools</string>
+ <key>IFPkgDescriptionTitle</key>
+ <string>Objective Caml</string>
+ <key>IFPkgDescriptionVersion</key>
+ <string>${VERSION}</string>
+ </dict>
+ </plist>
+EOF
+
+cat >Info.plist <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleGetInfoString</key>
+ <string>Objective Caml ${VERSION}</string>
+ <key>CFBundleIdentifier</key>
+ <string>fr.inria.ocaml</string>
+ <key>CFBundleName</key>
+ <string>Objective Caml</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${VERSION}</string>
+ <key>IFMajorVersion</key>
+ <integer>${VERSION_MAJOR}</integer>
+ <key>IFMinorVersion</key>
+ <integer>${VERSION_MINOR}</integer>
+ <key>IFPkgFlagAllowBackRev</key>
+ <true/>
+ <key>IFPkgFlagAuthorizationAction</key>
+ <string>AdminAuthorization</string>
+ <key>IFPkgFlagDefaultLocation</key>
+ <string>/usr/local</string>
+ <key>IFPkgFlagInstallFat</key>
+ <false/>
+ <key>IFPkgFlagIsRequired</key>
+ <false/>
+ <key>IFPkgFlagRelocatable</key>
+ <false/>
+ <key>IFPkgFlagRestartAction</key>
+ <string>NoRestart</string>
+ <key>IFPkgFlagRootVolumeOnly</key>
+ <true/>
+ <key>IFPkgFlagUpdateInstalledLanguages</key>
+ <false/>
+ <key>IFPkgFormatVersion</key>
+ <real>0.10000000149011612</real>
+</dict>
+</plist>
+EOF
+
+mkdir -p resources
+
+# stop here -> |
+cat >resources/ReadMe.txt <<EOF
+This package installs Objective Caml version ${VERSION}.
+You need Mac OS X 10.5.x (Leopard), with the
+XCode tools installed (v3.1.1 or later), and
+optionally X11.
+
+Files will be installed in the following directories:
+
+/usr/local/bin - command-line executables
+/usr/local/lib/ocaml - library and support files
+/usr/local/man - manual pages
+EOF
+
+chmod -R g-w root
+sudo chown -R root:wheel root
+
+/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \
+ -build -p "`pwd`/ocaml.pkg" -f "`pwd`/root" -i "`pwd`/Info.plist" \
+ -d "`pwd`/Description.plist" -r "`pwd`/resources"
+
+size=`du -s ocaml.pkg | cut -f 1`
+size=`expr $size + 8192`
+
+hdiutil create -sectors $size ocaml-rw.dmg
+name=`hdid -nomount ocaml-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
+volname="Objective Caml ${VERSION}"
+newfs_hfs -v "$volname" $name
+hdiutil detach $name
+
+name=`hdid ocaml-rw.dmg | grep Apple_HFS | cut -d ' ' -f 1`
+if test -d "/Volumes/$volname"; then
+ ditto -rsrcFork ocaml.pkg "/Volumes/$volname/ocaml.pkg"
+ cp resources/ReadMe.txt "/Volumes/$volname/"
+else
+ echo "Unable to mount the disk image as \"/Volumes/$volname\"" >&2
+ exit 3
+fi
+open "/Volumes/$volname"
+sleep 2
+hdiutil detach $name
+
+rm -rf "ocaml-${VERSION}.dmg"
+hdiutil convert ocaml-rw.dmg -format UDZO -o "ocaml-${VERSION}.dmg"
diff --git a/ocaml-binary-annot/tools/objinfo.ml b/ocaml-binary-annot/tools/objinfo.ml
new file mode 100644
index 0000000000..e9eb403135
--- /dev/null
+++ b/ocaml-binary-annot/tools/objinfo.ml
@@ -0,0 +1,269 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* Mehdi Dogguy, PPS laboratory, University Paris Diderot *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. Modifications Copyright 2010 Mehdi Dogguy, *)
+(* used and distributed as part of Objective Caml by permission from *)
+(* the author. This file is distributed under the terms of the *)
+(* Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Dump info on .cmi, .cmo, .cmx, .cma, .cmxa, .cmxs files
+ and on bytecode executables. *)
+
+open Printf
+open Misc
+open Config
+open Cmo_format
+open Clambda
+
+let input_stringlist ic len =
+ let get_string_list sect len =
+ let rec fold s e acc =
+ if e != len then
+ if sect.[e] = '\000' then
+ fold (e+1) (e+1) (String.sub sect s (e-s) :: acc)
+ else fold s (e+1) acc
+ else acc
+ in fold 0 0 []
+ in
+ let sect = String.create len in
+ let _ = really_input ic sect 0 len in
+ get_string_list sect len
+
+let print_name_crc (name, crc) =
+ printf "\t%s\t%s\n" (Digest.to_hex crc) name
+
+let print_line name =
+ printf "\t%s\n" name
+
+let print_cmo_infos cu =
+ printf "Unit name: %s\n" cu.cu_name;
+ print_string "Interfaces imported:\n";
+ List.iter print_name_crc cu.cu_imports;
+ printf "Uses unsafe features: ";
+ match cu.cu_primitives with
+ | [] -> printf "no\n"
+ | l ->
+ printf "YES\n";
+ printf "Primitives declared in this module:\n";
+ List.iter print_line l
+
+let rec print_approx_infos ppf = function
+ Value_closure(fundesc, approx) ->
+ Format.fprintf ppf "@[<2>function %s@ arity %i"
+ fundesc.fun_label fundesc.fun_arity;
+ if fundesc.fun_closed then begin
+ Format.fprintf ppf "@ (closed)"
+ end;
+ if fundesc.fun_inline <> None then begin
+ Format.fprintf ppf "@ (inline)"
+ end;
+ Format.fprintf ppf "@ -> @ %a@]" print_approx_infos approx
+ | Value_tuple approx ->
+ let tuple ppf approx =
+ for i = 0 to Array.length approx - 1 do
+ if i > 0 then Format.fprintf ppf ";@ ";
+ Format.fprintf ppf "%i: %a" i print_approx_infos approx.(i)
+ done in
+ Format.fprintf ppf "@[<hov 1>(%a)@]" tuple approx
+ | Value_unknown ->
+ Format.fprintf ppf "_"
+ | Value_integer n ->
+ Format.fprintf ppf "%d" n
+ | Value_constptr n ->
+ Format.fprintf ppf "%dp" n
+
+let print_spaced_string s =
+ printf " %s" s
+
+let print_cma_infos (lib : Cmo_format.library) =
+ printf "Force custom: %s\n" (if lib.lib_custom then "YES" else "no");
+ printf "Extra C object files:";
+ (* PR#4949: print in linking order *)
+ List.iter print_spaced_string (List.rev lib.lib_ccobjs);
+ printf "\nExtra C options:";
+ List.iter print_spaced_string lib.lib_ccopts;
+ printf "\n";
+ print_string "Extra dynamically-loaded libraries:";
+ List.iter print_spaced_string lib.lib_dllibs;
+ printf "\n";
+ List.iter print_cmo_infos lib.lib_units
+
+let print_cmi_infos name sign comps crcs =
+ printf "Unit name: %s\n" name;
+ printf "Interfaces imported:\n";
+ List.iter print_name_crc crcs
+
+let print_general_infos name crc defines cmi cmx =
+ printf "Name: %s\n" name;
+ printf "CRC of implementation: %s\n" (Digest.to_hex crc);
+ printf "Globals defined:\n";
+ List.iter print_line defines;
+ printf "Interfaces imported:\n";
+ List.iter print_name_crc cmi;
+ printf "Implementations imported:\n";
+ List.iter print_name_crc cmx
+
+open Cmx_format
+
+let print_cmx_infos (ui, crc) =
+ print_general_infos
+ ui.ui_name crc ui.ui_defines ui.ui_imports_cmi ui.ui_imports_cmx;
+ printf "Approximation:\n";
+ Format.fprintf Format.std_formatter " %a@." print_approx_infos ui.ui_approx;
+ let pr_funs _ fns =
+ List.iter (fun arity -> printf " %d" arity) fns in
+ printf "Currying functions:%a\n" pr_funs ui.ui_curry_fun;
+ printf "Apply functions:%a\n" pr_funs ui.ui_apply_fun
+
+let print_cmxs_infos header =
+ List.iter
+ (fun ui ->
+ print_general_infos
+ ui.dynu_name
+ ui.dynu_crc
+ ui.dynu_defines
+ ui.dynu_imports_cmi
+ ui.dynu_imports_cmx)
+ header.dynu_units
+
+let p_title title = printf "%s:\n" title
+
+let p_section title = function
+ | [] -> ()
+ | l ->
+ p_title title;
+ List.iter print_name_crc l
+
+let p_list title print = function
+ | [] -> ()
+ | l ->
+ p_title title;
+ List.iter print l
+
+let dump_byte ic =
+ Bytesections.read_toc ic;
+ let toc = Bytesections.toc () in
+ let toc = List.sort Pervasives.compare toc in
+ List.iter
+ (fun (section, _) ->
+ try
+ let len = Bytesections.seek_section ic section in
+ if len > 0 then match section with
+ | "CRCS" ->
+ p_section
+ "Imported units"
+ (input_value ic : (string * Digest.t) list)
+ | "DLLS" ->
+ p_list
+ "Used DLLs"
+ print_line
+ (input_stringlist ic len)
+ | "DLPT" ->
+ p_list
+ "Additional DLL paths"
+ print_line
+ (input_stringlist ic len)
+ | "PRIM" ->
+ p_list
+ "Primitives used"
+ print_line
+ (input_stringlist ic len)
+ | _ -> ()
+ with _ -> ()
+ )
+ toc
+
+let read_dyn_header filename ic =
+ let tempfile = Filename.temp_file "objinfo" ".out" in
+ let helper = Filename.concat Config.standard_library "objinfo_helper" in
+ try
+ try_finally
+ (fun () ->
+ let rc = Sys.command (sprintf "%s %s > %s"
+ (Filename.quote helper)
+ (Filename.quote filename)
+ tempfile) in
+ if rc <> 0 then failwith "cannot read";
+ let tc = open_in tempfile in
+ try_finally
+ (fun () ->
+ let ofs = Scanf.fscanf tc "%Ld" (fun x -> x) in
+ LargeFile.seek_in ic ofs;
+ Some(input_value ic : dynheader))
+ (fun () -> close_in tc))
+ (fun () -> remove_file tempfile)
+ with Failure _ | Sys_error _ -> None
+
+let dump_obj filename =
+ printf "File %s\n" filename;
+ let ic = open_in_bin filename in
+ let len_magic_number = String.length cmo_magic_number in
+ let magic_number = String.create len_magic_number in
+ really_input ic magic_number 0 len_magic_number;
+ if magic_number = cmo_magic_number then begin
+ let cu_pos = input_binary_int ic in
+ seek_in ic cu_pos;
+ let cu = (input_value ic : compilation_unit) in
+ close_in ic;
+ print_cmo_infos cu
+ end else if magic_number = cma_magic_number then begin
+ let toc_pos = input_binary_int ic in
+ seek_in ic toc_pos;
+ let toc = (input_value ic : library) in
+ close_in ic;
+ print_cma_infos toc
+ end else if magic_number = cmi_magic_number then begin
+ let (name, sign, comps) = input_value ic in
+ let crcs = input_value ic in
+ close_in ic;
+ print_cmi_infos name sign comps crcs
+ end else if magic_number = cmx_magic_number then begin
+ let ui = (input_value ic : unit_infos) in
+ let crc = Digest.input ic in
+ close_in ic;
+ print_cmx_infos (ui, crc)
+ end else if magic_number = cmxa_magic_number then begin
+ let li = (input_value ic : library_infos) in
+ close_in ic;
+ List.iter print_cmx_infos li.lib_units
+ end else begin
+ let pos_trailer = in_channel_length ic - len_magic_number in
+ let _ = seek_in ic pos_trailer in
+ let _ = really_input ic magic_number 0 len_magic_number in
+ if magic_number = Config.exec_magic_number then begin
+ dump_byte ic;
+ close_in ic
+ end else if Filename.check_suffix filename ".cmxs" then begin
+ flush stdout;
+ match read_dyn_header filename ic with
+ | None ->
+ printf "Unable to read info on file %s\n" filename;
+ exit 2
+ | Some header ->
+ if header.dynu_magic = Config.cmxs_magic_number then
+ print_cmxs_infos header
+ else begin
+ printf "Wrong magic number\n"; exit 2
+ end;
+ close_in ic
+ end else begin
+ printf "Not an OCaml object file\n"; exit 2
+ end
+ end
+
+let main() =
+ for i = 1 to Array.length Sys.argv - 1 do
+ dump_obj Sys.argv.(i)
+ done;
+ exit 0
+
+let _ = main ()
diff --git a/ocaml-binary-annot/tools/objinfo_helper.c b/ocaml-binary-annot/tools/objinfo_helper.c
new file mode 100644
index 0000000000..464720c296
--- /dev/null
+++ b/ocaml-binary-annot/tools/objinfo_helper.c
@@ -0,0 +1,92 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Mehdi Dogguy, PPS laboratory, University Paris Diderot */
+/* */
+/* Copyright 2010 Mehdi Dogguy. Used and distributed as part of */
+/* Objective Caml by permission from the author. This file is */
+/* distributed under the terms of the Q Public License version 1.0. */
+/***********************************************************************/
+
+#include "../config/s.h"
+#include "../byterun/mlvalues.h"
+#include "../byterun/alloc.h"
+#include <stdio.h>
+
+#ifdef HAS_LIBBFD
+#include <stdlib.h>
+#include <string.h>
+#include <bfd.h>
+
+int main(int argc, char ** argv)
+{
+ bfd *fd;
+ asection *sec;
+ file_ptr offset;
+ long st_size;
+ asymbol ** symbol_table;
+ long sym_count, i;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: objinfo_helper <dynamic library>\n");
+ return 2;
+ }
+
+ fd = bfd_openr(argv[1], "default");
+ if (!fd) {
+ fprintf(stderr, "Error opening file %s\n", argv[1]);
+ return 2;
+ }
+ if (! bfd_check_format (fd, bfd_object)) {
+ fprintf(stderr, "Error: wrong format\n");
+ bfd_close(fd);
+ return 2;
+ }
+
+ sec = bfd_get_section_by_name(fd, ".data");
+ if (! sec) {
+ fprintf(stderr, "Error: section .data not found\n");
+ bfd_close(fd);
+ return 2;
+ }
+
+ offset = sec->filepos;
+ st_size = bfd_get_dynamic_symtab_upper_bound (fd);
+ if (st_size <= 0) {
+ fprintf(stderr, "Error: size of section .data unknown\n");
+ bfd_close(fd);
+ return 2;
+ }
+
+ symbol_table = malloc(st_size);
+ if (! symbol_table) {
+ fprintf(stderr, "Error: out of memory\n");
+ bfd_close(fd);
+ return 2;
+ }
+
+ sym_count = bfd_canonicalize_dynamic_symtab (fd, symbol_table);
+
+ for (i = 0; i < sym_count; i++) {
+ if (strcmp(symbol_table[i]->name, "caml_plugin_header") == 0) {
+ printf("%ld\n", (long) (offset + symbol_table[i]->value));
+ bfd_close(fd);
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "Error: missing symbol caml_plugin_header\n");
+ bfd_close(fd);
+ return 2;
+}
+
+#else
+
+int main(int argc, char ** argv)
+{
+ fprintf(stderr, "BFD library unavailable, cannot print info on .cmxs files\n");
+ return 2;
+}
+
+#endif
diff --git a/ocaml-binary-annot/tools/ocaml-objcopy-macosx b/ocaml-binary-annot/tools/ocaml-objcopy-macosx
new file mode 100755
index 0000000000..cb2f703b4d
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocaml-objcopy-macosx
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Damien Doligez, projet Cristal, INRIA Rocquencourt #
+# #
+# Copyright 2005 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+
+TMP="${TMPDIR=/tmp}"
+TEMP="${TMP}"/ocaml-objcopy-$$.o
+UNDEF="${TMP}"/ocaml-objcopy-$$.sym
+
+usage () {
+ echo "usage: objcopy {--redefine-sym <old>=<new>} file.o" >&2
+ exit 2
+}
+
+: > "$UNDEF"
+
+while : ; do
+ case $# in
+ 0) break;;
+ *) case $1 in
+ --redefine-sym)
+ case $2 in
+ *=*) ALIAS="$ALIAS -i${2#*=}:${2%%=*}"
+ echo ${2%%=*} >>"$UNDEF"
+ ;;
+ *) usage;;
+ esac
+ shift 2
+ ;;
+ -*) usage;;
+ *) case $FILE in
+ "") FILE=$1; shift;;
+ *) usage;;
+ esac;;
+ esac;;
+ esac
+done
+
+ld -o "$TEMP" -r $ALIAS "$FILE"
+ld -o "$FILE" -r -unexported_symbols_list "$UNDEF" "$TEMP"
+
+rm -f "$TEMP" "$UNDEF"
diff --git a/ocaml-binary-annot/tools/ocaml299to3.ml b/ocaml-binary-annot/tools/ocaml299to3.ml
new file mode 100644
index 0000000000..b1dca8daaf
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocaml299to3.ml
@@ -0,0 +1,139 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Lexer299
+
+let input_buffer = Buffer.create 16383
+let input_function ic buf len =
+ let len = input ic buf 0 len in
+ Buffer.add_substring input_buffer buf 0 len;
+ len
+
+let output_buffer = Buffer.create 16383
+
+let modified = ref false
+
+let convert buffer =
+ let input_pos = ref 0 in
+ let copy_input stop =
+ Buffer.add_substring output_buffer (Buffer.contents input_buffer)
+ !input_pos (stop - !input_pos);
+ input_pos := stop
+ in
+ let last = ref (EOF, 0, 0) in
+ try while true do
+ let token = Lexer299.token buffer
+ and start = Lexing.lexeme_start buffer
+ and stop = Lexing.lexeme_end buffer
+ and last_token, last_start, last_stop = !last in
+ begin match token with
+ | LABEL l0 ->
+ let l = if l0 = "fun" then "f" else l0 in
+ begin match last_token with
+ | PREFIXOP "?(" ->
+ modified := true;
+ copy_input last_start;
+ Buffer.add_char output_buffer '?';
+ Buffer.add_string output_buffer l;
+ Buffer.add_string output_buffer ":(";
+ input_pos := stop
+ | QUESTION | LPAREN | LBRACE | SEMI | MINUSGREATER
+ | EQUAL | COLON | COLONGREATER
+ | VAL | MUTABLE | EXTERNAL | METHOD | OF ->
+ if l0 = "fun" then begin
+ modified := true;
+ copy_input start;
+ Buffer.add_string output_buffer l;
+ Buffer.add_char output_buffer ':';
+ input_pos := stop
+ end
+ | _ ->
+ modified := true;
+ copy_input start;
+ Buffer.add_char output_buffer '~';
+ Buffer.add_string output_buffer l;
+ Buffer.add_char output_buffer ':';
+ input_pos := stop
+ end
+ | LABELID l ->
+ modified := true;
+ begin match last_token with
+ | PREFIXOP "?(" ->
+ copy_input last_start;
+ Buffer.add_string output_buffer "?(";
+ Buffer.add_string output_buffer l;
+ input_pos := stop
+ | LPAREN ->
+ copy_input last_start;
+ Buffer.add_string output_buffer "~(";
+ Buffer.add_string output_buffer l;
+ input_pos := stop
+ | QUESTION ->
+ copy_input last_stop;
+ Buffer.add_string output_buffer l;
+ input_pos := stop
+ | _ ->
+ copy_input start;
+ Buffer.add_char output_buffer '~';
+ Buffer.add_string output_buffer l;
+ input_pos := stop
+ end
+ | EOF -> raise End_of_file
+ | _ -> ()
+ end;
+ if last_token = QUESTION && token = LPAREN then
+ last := (PREFIXOP "?(", last_start, stop)
+ else
+ last := (token, start, stop)
+ done with
+ End_of_file ->
+ copy_input (Buffer.length input_buffer)
+
+let convert_file name =
+ let ic = open_in name in
+ Buffer.clear input_buffer;
+ Buffer.clear output_buffer;
+ modified := false;
+ begin
+ try convert (Lexing.from_function (input_function ic)); close_in ic
+ with exn -> close_in ic; raise exn
+ end;
+ if !modified then begin
+ let backup = name ^ ".bak" in
+ if Sys.file_exists backup then Sys.remove name
+ else Sys.rename name backup;
+ let oc = open_out name in
+ Buffer.output_buffer oc output_buffer;
+ close_out oc
+ end
+
+let _ =
+ if Array.length Sys.argv < 2 || Sys.argv.(1) = "-h" || Sys.argv.(1) = "-help"
+ then begin
+ print_endline "Usage: ocaml299to3 <source file> ...";
+ print_endline "Description:";
+ print_endline
+ "Convert Objective Caml 2.99 O'Labl-style labels in implementation files to";
+ print_endline
+ "a syntax compatible with version 3. Also `fun:' labels are replaced by `f:'.";
+ print_endline "Other syntactic changes are not handled.";
+ print_endline "Old files are renamed to <file>.bak.";
+ print_endline "Interface files do not need label syntax conversion.";
+ exit 0
+ end;
+ for i = 1 to Array.length Sys.argv - 1 do
+ let name = Sys.argv.(i) in
+ prerr_endline ("Converting " ^ name);
+ Printexc.catch convert_file name
+ done
diff --git a/ocaml-binary-annot/tools/ocamlcp.ml b/ocaml-binary-annot/tools/ocamlcp.ml
new file mode 100644
index 0000000000..a86ae352fc
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlcp.ml
@@ -0,0 +1,137 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1998 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Printf
+
+let compargs = ref ([] : string list)
+let profargs = ref ([] : string list)
+let toremove = ref ([] : string list)
+
+let option opt () = compargs := opt :: !compargs
+let option_with_arg opt arg =
+ compargs := (Filename.quote arg) :: opt :: !compargs
+;;
+
+let make_archive = ref false;;
+let with_impl = ref false;;
+let with_intf = ref false;;
+let with_mli = ref false;;
+let with_ml = ref false;;
+
+let process_file filename =
+ if Filename.check_suffix filename ".ml" then with_ml := true;
+ if Filename.check_suffix filename ".mli" then with_mli := true;
+ compargs := (Filename.quote filename) :: !compargs
+;;
+
+let usage = "Usage: ocamlcp <options> <files>\noptions are:"
+
+let incompatible o =
+ fprintf stderr "ocamlcp: profiling is incompatible with the %s option\n" o;
+ exit 2
+
+module Options = Main_args.Make_bytecomp_options (struct
+ let _a () = make_archive := true; option "-a" ()
+ let _annot = option "-annot"
+ let _c = option "-c"
+ let _cc s = option_with_arg "-cc" s
+ let _cclib s = option_with_arg "-cclib" s
+ let _ccopt s = option_with_arg "-ccopt" s
+ let _config = option "-config"
+ let _custom = option "-custom"
+ let _dllib = option_with_arg "-dllib"
+ let _dllpath = option_with_arg "-dllpath"
+ let _dtypes = option "-dtypes"
+ let _g = option "-g"
+ let _i = option "-i"
+ let _I s = option_with_arg "-I" s
+ let _impl s = with_impl := true; option_with_arg "-impl" s
+ let _intf s = with_intf := true; option_with_arg "-intf" s
+ let _intf_suffix s = option_with_arg "-intf-suffix" s
+ let _labels = option "-labels"
+ let _linkall = option "-linkall"
+ let _make_runtime = option "-make-runtime"
+ let _no_app_funct = option "-no-app-funct"
+ let _noassert = option "-noassert"
+ let _nolabels = option "-nolabels"
+ let _noautolink = option "-noautolink"
+ let _nostdlib = option "-nostdlib"
+ let _o s = option_with_arg "-o" s
+ let _output_obj = option "-output-obj"
+ let _pack = option "-pack"
+ let _pp s = incompatible "-pp"
+ let _principal = option "-principal"
+ let _rectypes = option "-rectypes"
+ let _strict_sequence = option "-strict-sequence"
+ let _thread () = option "-thread" ()
+ let _vmthread () = option "-vmthread" ()
+ let _unsafe = option "-unsafe"
+ let _use_prims s = option_with_arg "-use-prims" s
+ let _use_runtime s = option_with_arg "-use-runtime" s
+ let _v = option "-v"
+ let _version = option "-version"
+ let _vnum = option "-vnum"
+ let _verbose = option "-verbose"
+ let _w = option_with_arg "-w"
+ let _warn_error = option_with_arg "-warn-error"
+ let _warn_help = option "-warn-help"
+ let _where = option "-where"
+ let _nopervasives = option "-nopervasives"
+ let _dparsetree = option "-dparsetree"
+ let _drawlambda = option "-drawlambda"
+ let _dlambda = option "-dlambda"
+ let _dinstr = option "-dinstr"
+ let anonymous = process_file
+end);;
+
+let add_profarg s =
+ profargs := (Filename.quote s) :: "-m" :: !profargs
+;;
+
+let optlist =
+ ("-p", Arg.String add_profarg,
+ "[afilmt] Profile constructs specified by argument (default fm):\n\
+ \032 a Everything\n\
+ \032 f Function calls and method calls\n\
+ \032 i if ... then ... else\n\
+ \032 l while and for loops\n\
+ \032 m match ... with\n\
+ \032 t try ... with")
+ :: Options.list
+in
+Arg.parse optlist process_file usage;
+if !with_impl && !with_intf then begin
+ fprintf stderr "ocamlcp cannot deal with both \"-impl\" and \"-intf\"\n";
+ fprintf stderr "please compile interfaces and implementations separately\n";
+ exit 2;
+end else if !with_impl && !with_mli then begin
+ fprintf stderr "ocamlcp cannot deal with both \"-impl\" and .mli files\n";
+ fprintf stderr "please compile interfaces and implementations separately\n";
+ exit 2;
+end else if !with_intf && !with_ml then begin
+ fprintf stderr "ocamlcp cannot deal with both \"-intf\" and .ml files\n";
+ fprintf stderr "please compile interfaces and implementations separately\n";
+ exit 2;
+end;
+if !with_impl then profargs := "-impl" :: !profargs;
+if !with_intf then profargs := "-intf" :: !profargs;
+let status =
+ Sys.command
+ (Printf.sprintf "ocamlc -pp \"ocamlprof -instrument %s\" %s %s"
+ (String.concat " " (List.rev !profargs))
+ (if !make_archive then "" else "profiling.cmo")
+ (String.concat " " (List.rev !compargs)))
+in
+exit status
+;;
diff --git a/ocaml-binary-annot/tools/ocamldep.ml b/ocaml-binary-annot/tools/ocamldep.ml
new file mode 100644
index 0000000000..72e03e91f9
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamldep.ml
@@ -0,0 +1,310 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1999 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Format
+open Location
+open Longident
+open Parsetree
+
+
+(* Print the dependencies *)
+
+let load_path = ref ([] : (string * string array) list)
+let native_only = ref false
+let force_slash = ref false
+let error_occurred = ref false
+let raw_dependencies = ref false
+
+(* Fix path to use '/' as directory separator instead of '\'.
+ Only under Windows. *)
+
+let fix_slash s =
+ if Sys.os_type = "Unix" then s else begin
+ let r = String.copy s in
+ for i = 0 to String.length r - 1 do
+ if r.[i] = '\\' then r.[i] <- '/'
+ done;
+ r
+ end
+
+let add_to_load_path dir =
+ try
+ let dir = Misc.expand_directory Config.standard_library dir in
+ let contents = Sys.readdir dir in
+ load_path := !load_path @ [dir, contents]
+ with Sys_error msg ->
+ fprintf Format.err_formatter "@[Bad -I option: %s@]@." msg;
+ error_occurred := true
+
+let find_file name =
+ let uname = String.uncapitalize name in
+ let rec find_in_array a pos =
+ if pos >= Array.length a then None else begin
+ let s = a.(pos) in
+ if s = name || s = uname then Some s else find_in_array a (pos + 1)
+ end in
+ let rec find_in_path = function
+ [] -> raise Not_found
+ | (dir, contents) :: rem ->
+ match find_in_array contents 0 with
+ Some truename ->
+ if dir = "." then truename else Filename.concat dir truename
+ | None -> find_in_path rem in
+ find_in_path !load_path
+
+let find_dependency modname (byt_deps, opt_deps) =
+ try
+ let filename = find_file (modname ^ ".mli") in
+ let basename = Filename.chop_suffix filename ".mli" in
+ let optname =
+ if Sys.file_exists (basename ^ ".ml")
+ then basename ^ ".cmx"
+ else basename ^ ".cmi" in
+ ((basename ^ ".cmi") :: byt_deps, optname :: opt_deps)
+ with Not_found ->
+ try
+ let filename = find_file (modname ^ ".ml") in
+ let basename = Filename.chop_suffix filename ".ml" in
+ let bytename =
+ basename ^ (if !native_only then ".cmx" else ".cmo") in
+ (bytename :: byt_deps, (basename ^ ".cmx") :: opt_deps)
+ with Not_found ->
+ (byt_deps, opt_deps)
+
+let (depends_on, escaped_eol) = (":", " \\\n ")
+
+let print_filename s =
+ let s = if !force_slash then fix_slash s else s in
+ if not (String.contains s ' ') then begin
+ print_string s;
+ end else begin
+ let rec count n i =
+ if i >= String.length s then n
+ else if s.[i] = ' ' then count (n+1) (i+1)
+ else count n (i+1)
+ in
+ let spaces = count 0 0 in
+ let result = String.create (String.length s + spaces) in
+ let rec loop i j =
+ if i >= String.length s then ()
+ else if s.[i] = ' ' then begin
+ result.[j] <- '\\';
+ result.[j+1] <- ' ';
+ loop (i+1) (j+2);
+ end else begin
+ result.[j] <- s.[i];
+ loop (i+1) (j+1);
+ end
+ in
+ loop 0 0;
+ print_string result;
+ end
+;;
+
+let print_dependencies target_file deps =
+ print_filename target_file; print_string depends_on;
+ let rec print_items pos = function
+ [] -> print_string "\n"
+ | dep :: rem ->
+ if pos + 1 + String.length dep <= 77 then begin
+ print_string " "; print_filename dep;
+ print_items (pos + String.length dep + 1) rem
+ end else begin
+ print_string escaped_eol; print_filename dep;
+ print_items (String.length dep + 4) rem
+ end in
+ print_items (String.length target_file + 1) deps
+
+let print_raw_dependencies source_file deps =
+ print_filename source_file; print_string ":";
+ Depend.StringSet.iter
+ (fun dep -> print_char ' '; print_string dep)
+ deps;
+ print_char '\n'
+
+(* Optionally preprocess a source file *)
+
+let preprocessor = ref None
+
+exception Preprocessing_error
+
+let preprocess sourcefile =
+ match !preprocessor with
+ None -> sourcefile
+ | Some pp ->
+ flush Pervasives.stdout;
+ let tmpfile = Filename.temp_file "camlpp" "" in
+ let comm = Printf.sprintf "%s %s > %s" pp sourcefile tmpfile in
+ if Sys.command comm <> 0 then begin
+ Misc.remove_file tmpfile;
+ raise Preprocessing_error
+ end;
+ tmpfile
+
+let remove_preprocessed inputfile =
+ match !preprocessor with
+ None -> ()
+ | Some _ -> Misc.remove_file inputfile
+
+(* Parse a file or get a dumped syntax tree in it *)
+
+let is_ast_file ic ast_magic =
+ try
+ let buffer = String.create (String.length ast_magic) in
+ really_input ic buffer 0 (String.length ast_magic);
+ if buffer = ast_magic then true
+ else if String.sub buffer 0 9 = String.sub ast_magic 0 9 then
+ failwith "Ocaml and preprocessor have incompatible versions"
+ else false
+ with End_of_file -> false
+
+let parse_use_file ic =
+ if is_ast_file ic Config.ast_impl_magic_number then
+ let _source_file = input_value ic in
+ [Ptop_def (input_value ic : Parsetree.structure)]
+ else begin
+ seek_in ic 0;
+ let lb = Lexing.from_channel ic in
+ Parse.use_file lb
+ end
+
+let parse_interface ic =
+ if is_ast_file ic Config.ast_intf_magic_number then
+ let _source_file = input_value ic in
+ (input_value ic : Parsetree.signature)
+ else begin
+ seek_in ic 0;
+ let lb = Lexing.from_channel ic in
+ Parse.interface lb
+ end
+
+(* Process one file *)
+
+let ml_file_dependencies source_file =
+ Depend.free_structure_names := Depend.StringSet.empty;
+ let input_file = preprocess source_file in
+ let ic = open_in_bin input_file in
+ try
+ let ast = parse_use_file ic in
+ Depend.add_use_file Depend.StringSet.empty ast;
+ if !raw_dependencies then begin
+ print_raw_dependencies source_file !Depend.free_structure_names
+ end else begin
+ let basename = Filename.chop_extension source_file in
+ let init_deps =
+ if Sys.file_exists (basename ^ ".mli")
+ then let cmi_name = basename ^ ".cmi" in ([cmi_name], [cmi_name])
+ else ([], []) in
+ let (byt_deps, opt_deps) =
+ Depend.StringSet.fold find_dependency
+ !Depend.free_structure_names init_deps in
+ print_dependencies (basename ^ ".cmo") byt_deps;
+ print_dependencies (basename ^ ".cmx") opt_deps
+ end;
+ close_in ic; remove_preprocessed input_file
+ with x ->
+ close_in ic; remove_preprocessed input_file; raise x
+
+let mli_file_dependencies source_file =
+ Depend.free_structure_names := Depend.StringSet.empty;
+ let input_file = preprocess source_file in
+ let ic = open_in_bin input_file in
+ try
+ let ast = parse_interface ic in
+ Depend.add_signature Depend.StringSet.empty ast;
+ if !raw_dependencies then begin
+ print_raw_dependencies source_file !Depend.free_structure_names
+ end else begin
+ let basename = Filename.chop_extension source_file in
+ let (byt_deps, opt_deps) =
+ Depend.StringSet.fold find_dependency
+ !Depend.free_structure_names ([], []) in
+ print_dependencies (basename ^ ".cmi") byt_deps
+ end;
+ close_in ic; remove_preprocessed input_file
+ with x ->
+ close_in ic; remove_preprocessed input_file; raise x
+
+type file_kind = ML | MLI;;
+
+let file_dependencies_as kind source_file =
+ Location.input_name := source_file;
+ try
+ if Sys.file_exists source_file then begin
+ match kind with
+ | ML -> ml_file_dependencies source_file
+ | MLI -> mli_file_dependencies source_file
+ end
+ with x ->
+ let report_err = function
+ | Lexer.Error(err, range) ->
+ fprintf Format.err_formatter "@[%a%a@]@."
+ Location.print_error range Lexer.report_error err
+ | Syntaxerr.Error err ->
+ fprintf Format.err_formatter "@[%a@]@."
+ Syntaxerr.report_error err
+ | Sys_error msg ->
+ fprintf Format.err_formatter "@[I/O error:@ %s@]@." msg
+ | Preprocessing_error ->
+ fprintf Format.err_formatter "@[Preprocessing error on file %s@]@."
+ source_file
+ | x -> raise x in
+ error_occurred := true;
+ report_err x
+
+let file_dependencies source_file =
+ if Filename.check_suffix source_file ".ml" then
+ file_dependencies_as ML source_file
+ else if Filename.check_suffix source_file ".mli" then
+ file_dependencies_as MLI source_file
+ else ()
+
+(* Entry point *)
+
+let usage = "Usage: ocamldep [options] <source files>\nOptions are:"
+
+let print_version () =
+ printf "ocamldep, version %s@." Sys.ocaml_version;
+ exit 0;
+;;
+
+let print_version_num () =
+ printf "%s@." Sys.ocaml_version;
+ exit 0;
+;;
+
+let _ =
+ Clflags.classic := false;
+ add_to_load_path Filename.current_dir_name;
+ Arg.parse [
+ "-I", Arg.String add_to_load_path,
+ "<dir> Add <dir> to the list of include directories";
+ "-impl", Arg.String (file_dependencies_as ML),
+ "<f> Process <f> as a .ml file";
+ "-intf", Arg.String (file_dependencies_as MLI),
+ "<f> Process <f> as a .mli file";
+ "-modules", Arg.Set raw_dependencies,
+ " Print module dependencies in raw form (not suitable for make)";
+ "-native", Arg.Set native_only,
+ " Generate dependencies for a pure native-code project (no .cmo files)";
+ "-pp", Arg.String(fun s -> preprocessor := Some s),
+ "<cmd> Pipe sources through preprocessor <cmd>";
+ "-slash", Arg.Set force_slash,
+ " (Windows) Use forward slash / instead of backslash \\ in file paths";
+ "-version", Arg.Unit print_version,
+ " Print version and exit";
+ "-vnum", Arg.Unit print_version_num,
+ " Print version number and exit";
+ ] file_dependencies usage;
+ exit (if !error_occurred then 2 else 0)
diff --git a/ocaml-binary-annot/tools/ocamlmklib.mlp b/ocaml-binary-annot/tools/ocamlmklib.mlp
new file mode 100644
index 0000000000..737749c17f
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlmklib.mlp
@@ -0,0 +1,281 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2001 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Printf
+open Myocamlbuild_config
+
+(* PR#4783: under Windows, don't use absolute paths because we do
+ not know where the binary distribution will be installed. *)
+let compiler_path name =
+ if Sys.os_type = "Win32" then name else Filename.concat bindir name
+
+let bytecode_objs = ref [] (* .cmo,.cma,.ml,.mli files to pass to ocamlc *)
+and native_objs = ref [] (* .cmx,.cmxa,.ml,.mli files to pass to ocamlopt *)
+and c_objs = ref [] (* .o, .a, .obj, .lib, .dll files to pass to mksharedlib and ar *)
+and caml_libs = ref [] (* -cclib to pass to ocamlc, ocamlopt *)
+and caml_opts = ref [] (* -ccopt to pass to ocamlc, ocamlopt *)
+and dynlink = ref supports_shared_libraries
+and failsafe = ref false (* whether to fall back on static build only *)
+and c_libs = ref [] (* libs to pass to mksharedlib and ocamlc -cclib *)
+and c_opts = ref [] (* options to pass to mksharedlib and ocamlc -ccopt *)
+and ld_opts = ref [] (* options to pass only to the linker *)
+and ocamlc = ref (compiler_path "ocamlc")
+and ocamlopt = ref (compiler_path "ocamlopt")
+and output = ref "a" (* Output name for Caml part of library *)
+and output_c = ref "" (* Output name for C part of library *)
+and rpath = ref [] (* rpath options *)
+and verbose = ref false
+
+let starts_with s pref =
+ String.length s >= String.length pref &&
+ String.sub s 0 (String.length pref) = pref
+let ends_with = Filename.check_suffix
+let chop_prefix s pref =
+ String.sub s (String.length pref) (String.length s - String.length pref)
+let chop_suffix = Filename.chop_suffix
+
+exception Bad_argument of string
+
+let print_version () =
+ printf "ocamlmklib, version %s\n" Sys.ocaml_version;
+ exit 0;
+;;
+
+let print_version_num () =
+ printf "%s\n" Sys.ocaml_version;
+ exit 0;
+;;
+
+let parse_arguments argv =
+ let i = ref 1 in
+ let next_arg () =
+ if !i + 1 >= Array.length argv
+ then raise (Bad_argument("Option " ^ argv.(!i) ^ " expects one argument"));
+ incr i; argv.(!i) in
+ while !i < Array.length argv do
+ let s = argv.(!i) in
+ if ends_with s ".cmo" || ends_with s ".cma" then
+ bytecode_objs := s :: !bytecode_objs
+ else if ends_with s ".cmx" || ends_with s ".cmxa" then
+ native_objs := s :: !native_objs
+ else if ends_with s ".ml" || ends_with s ".mli" then
+ (bytecode_objs := s :: !bytecode_objs;
+ native_objs := s :: !native_objs)
+ else if List.exists (ends_with s) [".o"; ".a"; ".obj"; ".lib"; ".dll"] then
+ c_objs := s :: !c_objs
+ else if s = "-cclib" then
+ caml_libs := next_arg () :: "-cclib" :: !caml_libs
+ else if s = "-ccopt" then
+ caml_opts := next_arg () :: "-ccopt" :: !caml_opts
+ else if s = "-custom" then
+ dynlink := false
+ else if s = "-I" then
+ caml_opts := next_arg () :: "-I" :: !caml_opts
+ else if s = "-failsafe" then
+ failsafe := true
+ else if s = "-h" || s = "-help" || s = "--help" then
+ raise (Bad_argument "")
+ else if s = "-ldopt" then
+ ld_opts := next_arg () :: !ld_opts
+ else if s = "-linkall" then
+ caml_opts := s :: !caml_opts
+ else if starts_with s "-l" then
+ c_libs := s :: !c_libs
+ else if starts_with s "-L" then
+ (c_opts := s :: !c_opts;
+ let l = chop_prefix s "-L" in
+ if not (Filename.is_relative l) then rpath := l :: !rpath)
+ else if s = "-ocamlc" then
+ ocamlc := next_arg ()
+ else if s = "-ocamlopt" then
+ ocamlopt := next_arg ()
+ else if s = "-o" then
+ output := next_arg()
+ else if s = "-oc" then
+ output_c := next_arg()
+ else if s = "-dllpath" || s = "-R" || s = "-rpath" then
+ rpath := next_arg() :: !rpath
+ else if starts_with s "-R" then
+ rpath := chop_prefix s "-R" :: !rpath
+ else if s = "-Wl,-rpath" then
+ (let a = next_arg() in
+ if starts_with a "-Wl,"
+ then rpath := chop_prefix a "-Wl," :: !rpath
+ else raise (Bad_argument("Option -Wl,-rpath expects a -Wl, argument")))
+ else if starts_with s "-Wl,-rpath," then
+ rpath := chop_prefix s "-Wl,-rpath," :: !rpath
+ else if starts_with s "-Wl,-R" then
+ rpath := chop_prefix s "-Wl,-R" :: !rpath
+ else if s = "-v" || s = "-verbose" then
+ verbose := true
+ else if s = "-version" then
+ print_version ()
+ else if s = "-vnum" then
+ print_version_num ()
+ else if starts_with s "-F" then
+ c_opts := s :: !c_opts
+ else if s = "-framework" then
+ (let a = next_arg() in c_opts := a :: s :: !c_opts)
+ else if starts_with s "-" then
+ prerr_endline ("Unknown option " ^ s)
+ else
+ raise (Bad_argument("Don't know what to do with " ^ s));
+ incr i
+ done;
+ List.iter
+ (fun r -> r := List.rev !r)
+ [ bytecode_objs; native_objs; caml_libs; caml_opts;
+ c_libs; c_objs; c_opts; ld_opts; rpath ];
+
+ if !output_c = "" then output_c := !output
+
+let usage = "\
+Usage: ocamlmklib [options] <.cmo|.cma|.cmx|.cmxa|.ml|.mli|.o|.a|.obj|.lib|.dll files>\n\
+Options are:\n\
+ -cclib <lib> C library passed to ocamlc -a or ocamlopt -a only\n\
+ -ccopt <opt> C option passed to ocamlc -a or ocamlopt -a only\n\
+ -custom disable dynamic loading\n\
+ -dllpath <dir> Add <dir> to the run-time search path for DLLs\n\
+ -F<dir> Specify a framework directory (MacOSX)\n\
+ -framework <name> Use framework <name> (MacOSX)\n\
+ -help Print this help message and exit\n\
+ --help Same as -help\n\
+ -h Same as -help\n\
+ -I <dir> Add <dir> to the path searched for Caml object files\n\
+ -failsafe fall back to static linking if DLL construction failed\n\
+ -ldopt <opt> C option passed to the shared linker only\n\
+ -linkall Build Caml archive with link-all behavior\n\
+ -l<lib> Specify a dependent C library\n\
+ -L<dir> Add <dir> to the path searched for C libraries\n\
+ -ocamlc <cmd> Use <cmd> in place of \"ocamlc\"\n\
+ -ocamlopt <cmd> Use <cmd> in place of \"ocamlopt\"\n\
+ -o <name> Generated Caml library is named <name>.cma or <name>.cmxa\n\
+ -oc <name> Generated C library is named dll<name>.so or lib<name>.a\n\
+ -rpath <dir> Same as -dllpath <dir>\n\
+ -R<dir> Same as -rpath\n\
+ -verbose Print commands before executing them\n\
+ -v same as -verbose\n\
+ -version Print version and exit\n\
+ -vnum Print version number and exit\n\
+ -Wl,-rpath,<dir> Same as -dllpath <dir>\n\
+ -Wl,-rpath -Wl,<dir> Same as -dllpath <dir>\n\
+ -Wl,-R<dir> Same as -dllpath <dir>\n\
+"
+
+let command cmd =
+ if !verbose then (print_string "+ "; print_string cmd; print_newline());
+ Sys.command cmd
+
+let scommand cmd =
+ if command cmd <> 0 then exit 2
+
+let safe_remove s =
+ try Sys.remove s with Sys_error _ -> ()
+
+let make_set l =
+ let rec merge l = function
+ [] -> List.rev l
+ | p :: r -> if List.mem p l then merge l r else merge (p::l) r
+ in
+ merge [] l
+
+let make_rpath flag =
+ if !rpath = [] || flag = ""
+ then ""
+ else flag ^ String.concat ":" (make_set !rpath)
+
+let make_rpath_ccopt flag =
+ if !rpath = [] || flag = ""
+ then ""
+ else "-ccopt " ^ flag ^ String.concat ":" (make_set !rpath)
+
+let prefix_list pref l =
+ List.map (fun s -> pref ^ s) l
+
+let prepostfix pre name post =
+ let base = Filename.basename name in
+ let dir = Filename.dirname name in
+ Filename.concat dir (pre ^ base ^ post)
+;;
+
+let transl_path s =
+ match Sys.os_type with
+ | "Win32" ->
+ let rec aux i =
+ if i = String.length s || s.[i] = ' ' then s
+ else (if s.[i] = '/' then s.[i] <- '\\'; aux (i + 1))
+ in aux 0
+ | _ -> s
+
+let build_libs () =
+ if !c_objs <> [] then begin
+ if !dynlink then begin
+ let retcode = command
+ (Printf.sprintf "%s -o %s %s %s %s %s %s"
+ mkdll
+ (prepostfix "dll" !output_c ext_dll)
+ (String.concat " " !c_objs)
+ (String.concat " " !c_opts)
+ (String.concat " " !ld_opts)
+ (make_rpath mksharedlibrpath)
+ (String.concat " " !c_libs)
+ )
+ in
+ if retcode <> 0 then if !failsafe then dynlink := false else exit 2
+ end;
+ safe_remove (prepostfix "lib" !output_c ext_lib);
+ scommand
+ (mklib (prepostfix "lib" !output_c ext_lib)
+ (String.concat " " !c_objs) "");
+ end;
+ if !bytecode_objs <> [] then
+ scommand
+ (sprintf "%s -a %s -o %s.cma %s %s -dllib -l%s -cclib -l%s %s %s %s %s"
+ (transl_path !ocamlc)
+ (if !dynlink then "" else "-custom")
+ !output
+ (String.concat " " !caml_opts)
+ (String.concat " " !bytecode_objs)
+ (Filename.basename !output_c)
+ (Filename.basename !output_c)
+ (String.concat " " (prefix_list "-ccopt " !c_opts))
+ (make_rpath_ccopt byteccrpath)
+ (String.concat " " (prefix_list "-cclib " !c_libs))
+ (String.concat " " !caml_libs));
+ if !native_objs <> [] then
+ scommand
+ (sprintf "%s -a -o %s.cmxa %s %s -cclib -l%s %s %s %s %s"
+ (transl_path !ocamlopt)
+ !output
+ (String.concat " " !caml_opts)
+ (String.concat " " !native_objs)
+ (Filename.basename !output_c)
+ (String.concat " " (prefix_list "-ccopt " !c_opts))
+ (make_rpath_ccopt nativeccrpath)
+ (String.concat " " (prefix_list "-cclib " !c_libs))
+ (String.concat " " !caml_libs))
+
+let _ =
+ try
+ parse_arguments Sys.argv;
+ build_libs()
+ with
+ | Bad_argument "" ->
+ prerr_string usage; exit 0
+ | Bad_argument s ->
+ prerr_endline s; prerr_string usage; exit 4
+ | Sys_error s ->
+ prerr_string "System error: "; prerr_endline s; exit 4
+ | x ->
+ raise x
diff --git a/ocaml-binary-annot/tools/ocamlmktop.ml b/ocaml-binary-annot/tools/ocamlmktop.ml
new file mode 100644
index 0000000000..3d353a8f59
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlmktop.ml
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+let _ =
+ let args = Ccomp.quote_files (List.tl (Array.to_list Sys.argv)) in
+ exit(Sys.command("ocamlc -linkall toplevellib.cma " ^ args ^ " topstart.cmo"))
diff --git a/ocaml-binary-annot/tools/ocamlmktop.tpl b/ocaml-binary-annot/tools/ocamlmktop.tpl
new file mode 100644
index 0000000000..477f7387ce
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlmktop.tpl
@@ -0,0 +1,16 @@
+#!/bin/sh
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Damien Doligez, projet Para, INRIA Rocquencourt #
+# #
+# Copyright 1999 Institut National de Recherche en Informatique et #
+# en Automatique. All rights reserved. This file is distributed #
+# under the terms of the Q Public License version 1.0. #
+# #
+#########################################################################
+
+# $Id$
+
+exec %%BINDIR%%/ocamlc -linkall toplevellib.cma "$@" topstart.cmo
diff --git a/ocaml-binary-annot/tools/ocamlprof.ml b/ocaml-binary-annot/tools/ocamlprof.ml
new file mode 100644
index 0000000000..f58712ec51
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlprof.ml
@@ -0,0 +1,503 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Damien Doligez and Francois Rouaix, INRIA Rocquencourt *)
+(* Ported to Caml Special Light by John Malecki *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Printf
+
+open Clflags
+open Config
+open Location
+open Misc
+open Parsetree
+
+(* User programs must not use identifiers that start with these prefixes. *)
+let idprefix = "__ocaml_prof_";;
+let modprefix = "OCAML__prof_";;
+
+(* Errors specific to the profiler *)
+exception Profiler of string
+
+(* Modes *)
+let instr_fun = ref false
+and instr_match = ref false
+and instr_if = ref false
+and instr_loops = ref false
+and instr_try = ref false
+
+let cur_point = ref 0
+and inchan = ref stdin
+and outchan = ref stdout
+
+(* To copy source fragments *)
+let copy_buffer = String.create 256
+
+let copy_chars_unix nchars =
+ let n = ref nchars in
+ while !n > 0 do
+ let m = input !inchan copy_buffer 0 (min !n 256) in
+ if m = 0 then raise End_of_file;
+ output !outchan copy_buffer 0 m;
+ n := !n - m
+ done
+
+let copy_chars_win32 nchars =
+ for i = 1 to nchars do
+ let c = input_char !inchan in
+ if c <> '\r' then output_char !outchan c
+ done
+
+let copy_chars =
+ match Sys.os_type with
+ "Win32" | "Cygwin" -> copy_chars_win32
+ | _ -> copy_chars_unix
+
+let copy next =
+ assert (next >= !cur_point);
+ seek_in !inchan !cur_point;
+ copy_chars (next - !cur_point);
+ cur_point := next;
+;;
+
+let prof_counter = ref 0;;
+
+let instr_mode = ref false
+
+type insert = Open | Close;;
+let to_insert = ref ([] : (insert * int) list);;
+
+let insert_action st en =
+ to_insert := (Open, st) :: (Close, en) :: !to_insert
+;;
+
+(* Producing instrumented code *)
+let add_incr_counter modul (kind,pos) =
+ copy pos;
+ match kind with
+ | Open ->
+ fprintf !outchan "(%sProfiling.incr %s%s_cnt %d; "
+ modprefix idprefix modul !prof_counter;
+ incr prof_counter;
+ | Close -> fprintf !outchan ")";
+;;
+
+let counters = ref (Array.create 0 0)
+
+(* User defined marker *)
+let special_id = ref ""
+
+(* Producing results of profile run *)
+let add_val_counter (kind,pos) =
+ if kind = Open then begin
+ copy pos;
+ fprintf !outchan "(* %s%d *) " !special_id !counters.(!prof_counter);
+ incr prof_counter;
+ end
+;;
+
+(* ************* rewrite ************* *)
+
+let insert_profile rw_exp ex =
+ let st = ex.pexp_loc.loc_start.Lexing.pos_cnum
+ and en = ex.pexp_loc.loc_end.Lexing.pos_cnum
+ and gh = ex.pexp_loc.loc_ghost
+ in
+ if gh || st = en then
+ rw_exp true ex
+ else begin
+ insert_action st en;
+ rw_exp false ex;
+ end
+;;
+
+
+let pos_len = ref 0
+
+let init_rewrite modes mod_name =
+ cur_point := 0;
+ if !instr_mode then begin
+ fprintf !outchan "module %sProfiling = Profiling;; " modprefix;
+ fprintf !outchan "let %s%s_cnt = Array.create 000000000" idprefix mod_name;
+ pos_len := pos_out !outchan;
+ fprintf !outchan
+ " 0;; Profiling.counters := \
+ (\"%s\", (\"%s\", %s%s_cnt)) :: !Profiling.counters;; "
+ mod_name modes idprefix mod_name;
+ end
+
+let final_rewrite add_function =
+ to_insert := Sort.list (fun x y -> snd x < snd y) !to_insert;
+ prof_counter := 0;
+ List.iter add_function !to_insert;
+ copy (in_channel_length !inchan);
+ if !instr_mode then begin
+ let len = string_of_int !prof_counter in
+ if String.length len > 9 then raise (Profiler "too many counters");
+ seek_out !outchan (!pos_len - String.length len);
+ output_string !outchan len
+ end;
+ (* Cannot close because outchan is stdout and Format doesn't like
+ a closed stdout.
+ close_out !outchan;
+ *)
+;;
+
+let rec rewrite_patexp_list iflag l =
+ rewrite_exp_list iflag (List.map snd l)
+
+and rewrite_patlexp_list iflag l =
+ rewrite_exp_list iflag (List.map snd l)
+
+and rewrite_labelexp_list iflag l =
+ rewrite_exp_list iflag (List.map snd l)
+
+and rewrite_exp_list iflag l =
+ List.iter (rewrite_exp iflag) l
+
+and rewrite_exp iflag sexp =
+ if iflag then insert_profile rw_exp sexp
+ else rw_exp false sexp
+
+and rw_exp iflag sexp =
+ match sexp.pexp_desc with
+ Pexp_ident lid -> ()
+ | Pexp_constant cst -> ()
+
+ | Pexp_let(_, spat_sexp_list, sbody) ->
+ rewrite_patexp_list iflag spat_sexp_list;
+ rewrite_exp iflag sbody
+
+ | Pexp_function (_, _, caselist) ->
+ if !instr_fun then
+ rewrite_function iflag caselist
+ else
+ rewrite_patlexp_list iflag caselist
+
+ | Pexp_match(sarg, caselist) ->
+ rewrite_exp iflag sarg;
+ if !instr_match && not sexp.pexp_loc.loc_ghost then
+ rewrite_funmatching caselist
+ else
+ rewrite_patlexp_list iflag caselist
+
+ | Pexp_try(sbody, caselist) ->
+ rewrite_exp iflag sbody;
+ if !instr_try && not sexp.pexp_loc.loc_ghost then
+ rewrite_trymatching caselist
+ else
+ rewrite_patexp_list iflag caselist
+
+ | Pexp_apply(sfunct, sargs) ->
+ rewrite_exp iflag sfunct;
+ rewrite_exp_list iflag (List.map snd sargs)
+
+ | Pexp_tuple sexpl ->
+ rewrite_exp_list iflag sexpl
+
+ | Pexp_construct(_, None, _) -> ()
+ | Pexp_construct(_, Some sarg, _) ->
+ rewrite_exp iflag sarg
+
+ | Pexp_variant(_, None) -> ()
+ | Pexp_variant(_, Some sarg) ->
+ rewrite_exp iflag sarg
+
+ | Pexp_record(lid_sexp_list, None) ->
+ rewrite_labelexp_list iflag lid_sexp_list
+ | Pexp_record(lid_sexp_list, Some sexp) ->
+ rewrite_exp iflag sexp;
+ rewrite_labelexp_list iflag lid_sexp_list
+
+ | Pexp_field(sarg, _) ->
+ rewrite_exp iflag sarg
+
+ | Pexp_setfield(srecord, _, snewval) ->
+ rewrite_exp iflag srecord;
+ rewrite_exp iflag snewval
+
+ | Pexp_array(sargl) ->
+ rewrite_exp_list iflag sargl
+
+ | Pexp_ifthenelse(scond, sifso, None) ->
+ rewrite_exp iflag scond;
+ rewrite_ifbody iflag sexp.pexp_loc.loc_ghost sifso
+ | Pexp_ifthenelse(scond, sifso, Some sifnot) ->
+ rewrite_exp iflag scond;
+ rewrite_ifbody iflag sexp.pexp_loc.loc_ghost sifso;
+ rewrite_ifbody iflag sexp.pexp_loc.loc_ghost sifnot
+
+ | Pexp_sequence(sexp1, sexp2) ->
+ rewrite_exp iflag sexp1;
+ rewrite_exp iflag sexp2
+
+ | Pexp_while(scond, sbody) ->
+ rewrite_exp iflag scond;
+ if !instr_loops && not sexp.pexp_loc.loc_ghost
+ then insert_profile rw_exp sbody
+ else rewrite_exp iflag sbody
+
+ | Pexp_for(_, slow, shigh, _, sbody) ->
+ rewrite_exp iflag slow;
+ rewrite_exp iflag shigh;
+ if !instr_loops && not sexp.pexp_loc.loc_ghost
+ then insert_profile rw_exp sbody
+ else rewrite_exp iflag sbody
+
+ | Pexp_constraint(sarg, _, _) ->
+ rewrite_exp iflag sarg
+
+ | Pexp_when(scond, sbody) ->
+ rewrite_exp iflag scond;
+ rewrite_exp iflag sbody
+
+ | Pexp_send (sobj, _) ->
+ rewrite_exp iflag sobj
+
+ | Pexp_new _ -> ()
+
+ | Pexp_setinstvar (_, sarg) ->
+ rewrite_exp iflag sarg
+
+ | Pexp_override l ->
+ List.iter (fun (_, sexp) -> rewrite_exp iflag sexp) l
+
+ | Pexp_letmodule (_, smod, sexp) ->
+ rewrite_mod iflag smod;
+ rewrite_exp iflag sexp
+
+ | Pexp_assert (cond) -> rewrite_exp iflag cond
+ | Pexp_assertfalse -> ()
+
+ | Pexp_lazy (expr) -> rewrite_exp iflag expr
+
+ | Pexp_poly (sexp, _) -> rewrite_exp iflag sexp
+
+ | Pexp_object (_, fieldl) ->
+ List.iter (rewrite_class_field iflag) fieldl
+
+ | Pexp_newtype (_, sexp) -> rewrite_exp iflag sexp
+ | Pexp_open (_, e) -> rewrite_exp iflag e
+ | Pexp_pack (smod) -> rewrite_mod iflag smod
+
+and rewrite_ifbody iflag ghost sifbody =
+ if !instr_if && not ghost then
+ insert_profile rw_exp sifbody
+ else
+ rewrite_exp iflag sifbody
+
+(* called only when !instr_fun *)
+and rewrite_annotate_exp_list l =
+ List.iter
+ (function
+ | {pexp_desc = Pexp_when(scond, sbody)}
+ -> insert_profile rw_exp scond;
+ insert_profile rw_exp sbody;
+ | {pexp_desc = Pexp_constraint(sbody, _, _)} (* let f x : t = e *)
+ -> insert_profile rw_exp sbody
+ | sexp -> insert_profile rw_exp sexp)
+ l
+
+and rewrite_function iflag = function
+ | [spat, ({pexp_desc = Pexp_function _} as sexp)] -> rewrite_exp iflag sexp
+ | l -> rewrite_funmatching l
+
+and rewrite_funmatching l =
+ rewrite_annotate_exp_list (List.map snd l)
+
+and rewrite_trymatching l =
+ rewrite_annotate_exp_list (List.map snd l)
+
+(* Rewrite a class definition *)
+
+and rewrite_class_field iflag =
+ function
+ Pcf_inher (_, cexpr, _) -> rewrite_class_expr iflag cexpr
+ | Pcf_val (_, _, _, sexp, _) -> rewrite_exp iflag sexp
+ | Pcf_meth (_, _, _, ({pexp_desc = Pexp_function _} as sexp), _) ->
+ rewrite_exp iflag sexp
+ | Pcf_meth (_, _, _, sexp, loc) ->
+ if !instr_fun && not loc.loc_ghost then insert_profile rw_exp sexp
+ else rewrite_exp iflag sexp
+ | Pcf_let(_, spat_sexp_list, _) ->
+ rewrite_patexp_list iflag spat_sexp_list
+ | Pcf_init sexp ->
+ rewrite_exp iflag sexp
+ | Pcf_valvirt _ | Pcf_virt _ | Pcf_cstr _ -> ()
+
+and rewrite_class_expr iflag cexpr =
+ match cexpr.pcl_desc with
+ Pcl_constr _ -> ()
+ | Pcl_structure (_, fields) ->
+ List.iter (rewrite_class_field iflag) fields
+ | Pcl_fun (_, _, _, cexpr) ->
+ rewrite_class_expr iflag cexpr
+ | Pcl_apply (cexpr, exprs) ->
+ rewrite_class_expr iflag cexpr;
+ List.iter (rewrite_exp iflag) (List.map snd exprs)
+ | Pcl_let (_, spat_sexp_list, cexpr) ->
+ rewrite_patexp_list iflag spat_sexp_list;
+ rewrite_class_expr iflag cexpr
+ | Pcl_constraint (cexpr, _) ->
+ rewrite_class_expr iflag cexpr
+
+and rewrite_class_declaration iflag cl =
+ rewrite_class_expr iflag cl.pci_expr
+
+(* Rewrite a module expression or structure expression *)
+
+and rewrite_mod iflag smod =
+ match smod.pmod_desc with
+ Pmod_ident lid -> ()
+ | Pmod_structure sstr -> List.iter (rewrite_str_item iflag) sstr
+ | Pmod_functor(param, smty, sbody) -> rewrite_mod iflag sbody
+ | Pmod_apply(smod1, smod2) -> rewrite_mod iflag smod1; rewrite_mod iflag smod2
+ | Pmod_constraint(smod, smty) -> rewrite_mod iflag smod
+ | Pmod_unpack(sexp) -> rewrite_exp iflag sexp
+
+and rewrite_str_item iflag item =
+ match item.pstr_desc with
+ Pstr_eval exp -> rewrite_exp iflag exp
+ | Pstr_value(_, exps)
+ -> List.iter (function (_,exp) -> rewrite_exp iflag exp) exps
+ | Pstr_module(name, smod) -> rewrite_mod iflag smod
+ | Pstr_class classes -> List.iter (rewrite_class_declaration iflag) classes
+ | _ -> ()
+
+(* Rewrite a .ml file *)
+let rewrite_file srcfile add_function =
+ inchan := open_in_bin srcfile;
+ let lb = Lexing.from_channel !inchan in
+ Location.input_name := srcfile;
+ Location.init lb srcfile;
+ List.iter (rewrite_str_item false) (Parse.implementation lb);
+ final_rewrite add_function;
+ close_in !inchan
+
+(* Copy a non-.ml file without change *)
+let null_rewrite srcfile =
+ inchan := open_in_bin srcfile;
+ copy (in_channel_length !inchan);
+ close_in !inchan
+;;
+
+(* Setting flags from saved config *)
+let set_flags s =
+ for i = 0 to String.length s - 1 do
+ match String.get s i with
+ 'f' -> instr_fun := true
+ | 'm' -> instr_match := true
+ | 'i' -> instr_if := true
+ | 'l' -> instr_loops := true
+ | 't' -> instr_try := true
+ | 'a' -> instr_fun := true; instr_match := true;
+ instr_if := true; instr_loops := true;
+ instr_try := true
+ | _ -> ()
+ done
+
+(* Command-line options *)
+
+let modes = ref "fm"
+let dumpfile = ref "ocamlprof.dump"
+
+(* Process a file *)
+
+let process_intf_file filename = null_rewrite filename;;
+
+let process_impl_file filename =
+ let modname = Filename.basename(Filename.chop_extension filename) in
+ (* FIXME should let modname = String.capitalize modname *)
+ if !instr_mode then begin
+ (* Instrumentation mode *)
+ set_flags !modes;
+ init_rewrite !modes modname;
+ rewrite_file filename (add_incr_counter modname);
+ end else begin
+ (* Results mode *)
+ let ic = open_in_bin !dumpfile in
+ let allcounters =
+ (input_value ic : (string * (string * int array)) list) in
+ close_in ic;
+ let (modes, cv) =
+ try
+ List.assoc modname allcounters
+ with Not_found ->
+ raise(Profiler("Module " ^ modname ^ " not used in this profile."))
+ in
+ counters := cv;
+ set_flags modes;
+ init_rewrite modes modname;
+ rewrite_file filename add_val_counter;
+ end
+;;
+
+let process_anon_file filename =
+ if Filename.check_suffix filename ".ml" then
+ process_impl_file filename
+ else
+ process_intf_file filename
+;;
+
+(* Main function *)
+
+open Format
+
+let usage = "Usage: ocamlprof <options> <files>\noptions are:"
+
+let print_version () =
+ printf "ocamlprof, version %s@." Sys.ocaml_version;
+ exit 0;
+;;
+
+let print_version_num () =
+ printf "%s@." Sys.ocaml_version;
+ exit 0;
+;;
+
+let main () =
+ try
+ Warnings.parse_options false "a";
+ Arg.parse [
+ "-f", Arg.String (fun s -> dumpfile := s),
+ "<file> Use <file> as dump file (default ocamlprof.dump)";
+ "-F", Arg.String (fun s -> special_id := s),
+ "<s> Insert string <s> with the counts";
+ "-impl", Arg.String process_impl_file,
+ "<file> Process <file> as a .ml file";
+ "-instrument", Arg.Set instr_mode, " (undocumented)";
+ "-intf", Arg.String process_intf_file,
+ "<file> Process <file> as a .mli file";
+ "-m", Arg.String (fun s -> modes := s), "<flags> (undocumented)";
+ "-version", Arg.Unit print_version,
+ " Print version and exit";
+ "-vnum", Arg.Unit print_version_num,
+ " Print version number and exit";
+ ] process_anon_file usage;
+ exit 0
+ with x ->
+ let report_error ppf = function
+ | Lexer.Error(err, range) ->
+ fprintf ppf "@[%a%a@]@."
+ Location.print_error range Lexer.report_error err
+ | Syntaxerr.Error err ->
+ fprintf ppf "@[%a@]@."
+ Syntaxerr.report_error err
+ | Profiler msg ->
+ fprintf ppf "@[%s@]@." msg
+ | Sys_error msg ->
+ fprintf ppf "@[I/O error:@ %s@]@." msg
+ | x -> raise x in
+ report_error Format.err_formatter x;
+ exit 2
+
+let _ = main ()
diff --git a/ocaml-binary-annot/tools/ocamlsize b/ocaml-binary-annot/tools/ocamlsize
new file mode 100755
index 0000000000..659543d593
--- /dev/null
+++ b/ocaml-binary-annot/tools/ocamlsize
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+foreach $f (@ARGV) {
+ open(FILE, $f) || die("Cannot open $f");
+ seek(FILE, -16, 2);
+ $num_sections = do read_int();
+ read(FILE, $magic, 12);
+ seek(FILE, -16 - 8 * $num_sections, 2);
+ @secname = ();
+ @seclength = ();
+ %length = ();
+ for ($i = 0; $i < $num_sections; $i++) {
+ read(FILE, $sec, 4);
+ $secname[$i] = $sec;
+ $seclength[$i] = do read_int();
+ $length{$sec} = $seclength[$i];
+ }
+ print $f, ":\n" if ($#ARGV > 0);
+ $path =
+ $length{'RNTM'} > 0 ?
+ do read_section('RNTM') :
+ "(default runtime)\n";
+ printf ("\tcode: %-7d data: %-7d symbols: %-7d debug: %-7d\n",
+ $length{'CODE'}, $length{'DATA'},
+ $length{'SYMB'}, $length{'DBUG'});
+ printf ("\tmagic number: %s runtime system: %s",
+ $magic, $path);
+ close(FILE);
+}
+
+sub read_int {
+ read(FILE, $buff, 4) == 4 || die("Truncated bytecode file $f");
+ @int = unpack("C4", $buff);
+ return ($int[0] << 24) + ($int[1] << 16) + ($int[2] << 8) + $int[3];
+}
+
+sub read_section {
+ local ($sec) = @_;
+ local ($i, $ofs, $data);
+ for ($i = $num_sections - 1; $i >= 0; $i--) {
+ $ofs += $seclength[$i];
+ if ($secname[$i] eq $sec) {
+ seek(FILE, -16 - 8 * $num_sections - $ofs, 2);
+ read(FILE, $data, $seclength[$i]);
+ return $data;
+ }
+ }
+ return '';
+}
diff --git a/ocaml-binary-annot/tools/primreq.ml b/ocaml-binary-annot/tools/primreq.ml
new file mode 100644
index 0000000000..dcace11ba7
--- /dev/null
+++ b/ocaml-binary-annot/tools/primreq.ml
@@ -0,0 +1,90 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1999 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Determine the set of C primitives required by the given .cmo and .cma
+ files *)
+
+open Config
+open Cmo_format
+
+module StringSet = Set.Make(struct type t = string let compare = compare end)
+
+let defined = ref true
+let used = ref false
+let exclude_file = ref ""
+
+let primitives = ref StringSet.empty
+
+let scan_reloc = function
+ (Reloc_primitive s, _) -> primitives := StringSet.add s !primitives
+ | _ -> ()
+
+let scan_prim s =
+ primitives := StringSet.add s !primitives
+
+let scan_info cu =
+ if !used then List.iter scan_reloc cu.cu_reloc;
+ if !defined then List.iter scan_prim cu.cu_primitives
+
+let scan_obj filename =
+ let ic = open_in_bin filename in
+ let buffer = String.create (String.length cmo_magic_number) in
+ really_input ic buffer 0 (String.length cmo_magic_number);
+ if buffer = cmo_magic_number then begin
+ let cu_pos = input_binary_int ic in
+ seek_in ic cu_pos;
+ let cu = (input_value ic : compilation_unit) in
+ close_in ic;
+ scan_info cu
+ end else
+ if buffer = cma_magic_number then begin
+ let toc_pos = input_binary_int ic in
+ seek_in ic toc_pos;
+ let toc = (input_value ic : library) in
+ close_in ic;
+ List.iter scan_info toc.lib_units
+ end else begin
+ prerr_endline "Not an object file"; exit 2
+ end
+
+let exclude filename =
+ let ic = open_in filename in
+ try
+ while true do
+ let s = input_line ic in
+ primitives := StringSet.remove s !primitives
+ done
+ with End_of_file -> close_in ic
+ | x -> close_in ic; raise x
+
+let main() =
+ Arg.parse
+ ["-used", Arg.Unit(fun () -> used := true; defined := false),
+ "show primitives referenced in the object files";
+ "-defined", Arg.Unit(fun () -> defined := true; used := false),
+ "show primitives defined in the object files (default)";
+ "-all", Arg.Unit(fun () -> defined := true; used := true),
+ "show primitives defined or referenced in the object files";
+ "-exclude", Arg.String(fun s -> exclude_file := s),
+ "<file> don't print the primitives mentioned in <file>"]
+ scan_obj
+ "Usage: primreq [options] <.cmo and .cma files>\nOptions are:";
+ if String.length !exclude_file > 0 then exclude !exclude_file;
+ StringSet.iter
+ (fun s ->
+ if s.[0] <> '%' then begin print_string s; print_newline() end)
+ !primitives;
+ exit 0
+
+let _ = main ()
diff --git a/ocaml-binary-annot/tools/profiling.ml b/ocaml-binary-annot/tools/profiling.ml
new file mode 100644
index 0000000000..9c6d9dd02b
--- /dev/null
+++ b/ocaml-binary-annot/tools/profiling.ml
@@ -0,0 +1,56 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Damien Doligez and Francois Rouaix, INRIA Rocquencourt *)
+(* Ported to Caml Special Light by John Malecki and Xavier Leroy *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU Library General Public License, with *)
+(* the special exception on linking described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Run-time library for profiled programs *)
+
+type profiling_counters = (string * (string * int array)) list
+
+let counters = ref ([] : profiling_counters);;
+let incr a i = a.(i) <- a.(i) + 1;;
+
+exception Bad_profile
+
+let dump_counters () =
+ let dumpfile =
+ try Sys.getenv "OCAMLPROF_DUMP" with Not_found -> "ocamlprof.dump"
+ in
+ begin try
+ let ic = open_in_bin dumpfile in
+ let prevl = (input_value ic : profiling_counters) in
+ close_in ic;
+ List.iter2
+ (fun (curname, (curmodes,curcount)) (prevname, (prevmodes,prevcount)) ->
+ if curname <> prevname
+ || curmodes <> prevmodes
+ || Array.length curcount <> Array.length prevcount
+ then raise Bad_profile)
+ !counters prevl;
+ List.iter2
+ (fun (curname, (_,curcount)) (prevname, (_,prevcount)) ->
+ for i = 0 to Array.length curcount - 1 do
+ curcount.(i) <- curcount.(i) + prevcount.(i)
+ done)
+ !counters prevl
+ with _ -> ()
+ end;
+ begin try
+ let oc = open_out_bin dumpfile in
+ output_value oc !counters;
+ close_out oc
+ with _ -> ()
+ end
+
+let _ = at_exit dump_counters
diff --git a/ocaml-binary-annot/tools/profiling.mli b/ocaml-binary-annot/tools/profiling.mli
new file mode 100644
index 0000000000..ca8486f436
--- /dev/null
+++ b/ocaml-binary-annot/tools/profiling.mli
@@ -0,0 +1,20 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Damien Doligez and Francois Rouaix, INRIA Rocquencourt *)
+(* Ported to Objective Caml by John Malecki and Xavier Leroy *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU Library General Public License, with *)
+(* the special exception on linking described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Run-time library for profiled programs *)
+
+val counters: (string * (string * int array)) list ref;;
+val incr: int array -> int -> unit;;
diff --git a/ocaml-binary-annot/tools/scrapelabels.ml b/ocaml-binary-annot/tools/scrapelabels.ml
new file mode 100644
index 0000000000..dc43e97b70
--- /dev/null
+++ b/ocaml-binary-annot/tools/scrapelabels.ml
@@ -0,0 +1,289 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2001 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open StdLabels
+open Lexer301
+
+let input_buffer = Buffer.create 16383
+let input_function ic buf len =
+ let len = input ic buf 0 len in
+ Buffer.add_substring input_buffer buf 0 len;
+ len
+
+let output_buffer = Buffer.create 16383
+
+let modified = ref false
+
+let modules =
+ ref [ "Arg"; "BigArray"; "Buffer"; "Condition"; "Dbm"; "Digest"; "Dynlink";
+ "Event"; "Filename"; "Format"; "Gc"; "Genlex"; "Graphics";
+ "Lexing"; "Marshal"; "Mutex"; "Parsing"; "Pervasives"; "Queue";
+ "Sort"; "Stack"; "Str"; "Stream"; "Sys";
+ "Thread"; "ThreadUnix"; "Weak" ]
+
+let stdlabels = ["Array"; "List"; "String"]
+let morelabels = ["Hashtbl"; "Map"; "Set"]
+let alllabels = ref false
+let noopen = ref false
+
+exception Closing of token
+
+let convert_impl buffer =
+ let input_pos = ref 0 in
+ let copy_input stop =
+ Buffer.add_substring output_buffer (Buffer.contents input_buffer)
+ !input_pos (stop - !input_pos);
+ input_pos := stop
+ in
+ let next_token () =
+ let token = Lexer301.token buffer
+ and start = Lexing.lexeme_start buffer
+ and stop = Lexing.lexeme_end buffer in
+ match token with
+ RPAREN | RBRACKET |BARRBRACKET | GREATERRBRACKET | END
+ | RBRACE | GREATERRBRACE ->
+ raise (Closing token)
+ | EOF ->
+ raise End_of_file
+ | _ ->
+ (token, start, stop)
+ in
+ let openunix = ref None and openstd = ref None and openmore = ref None in
+ let rec may_start (token, s, e) =
+ match token with
+ LIDENT _ -> search_start (dropext (next_token ()))
+ | UIDENT m when List.mem m !modules ->
+ may_discard (dropext (next_token ()))
+ | UIDENT m ->
+ List.iter ~f:
+ (fun (set,r) ->
+ if !r = None && List.mem m ~set then r := Some true)
+ [stdlabels, openstd; ["Unix"], openunix; morelabels, openmore];
+ search_start (next_token ())
+ | _ -> search_start (token, s, e)
+
+ and dropext (token, s, e) =
+ match token with
+ DOT ->
+ let (token, s, e) = next_token () in
+ begin match token with
+ LPAREN | LBRACKET | LBRACE ->
+ process_paren (token, s, e);
+ dropext (next_token ())
+ | UIDENT _ | LIDENT _ ->
+ dropext (next_token ())
+ | _ ->
+ prerr_endline ("bad index at position " ^ string_of_int s);
+ (token, s, e)
+ end
+ | _ ->
+ (token, s, e)
+
+ and may_discard (token, s, e) =
+ match token with
+ TILDE | LABEL _ ->
+ modified := true;
+ copy_input s; input_pos := e;
+ may_discard (next_token ())
+ | _ when !alllabels ->
+ may_discard (next_token ())
+ | LPAREN | LBRACKET | LBRACKETBAR | LBRACKETLESS | BEGIN
+ | LBRACE | LBRACELESS | STRUCT | SIG | OBJECT->
+ process_paren (token, s, e);
+ may_discard (next_token ())
+ | PREFIXOP _ ->
+ may_discard (next_token ())
+ | LIDENT _ | UIDENT _ ->
+ may_discard (dropext (next_token ()))
+ | BACKQUOTE ->
+ ignore (next_token ());
+ may_discard (next_token ())
+ | INT _ | CHAR _ | STRING _ | FLOAT _ | FALSE | TRUE ->
+ may_discard (next_token ())
+ | _ ->
+ search_start (token, s, e)
+
+ and search_start (token, s, e) =
+ match token with
+ LPAREN | LBRACKET | LBRACKETBAR | LBRACKETLESS | BEGIN
+ | LBRACE | LBRACELESS | STRUCT | SIG | OBJECT ->
+ process_paren (token, s, e);
+ search_start (next_token ())
+ | EQUAL | SEMI | SEMISEMI | MINUSGREATER | LESSMINUS | COMMA
+ | IF | THEN | ELSE | WHILE | TO | DOWNTO | DO | IN | MATCH | TRY
+ | INFIXOP0 _ | INFIXOP1 _ | INFIXOP2 _ | INFIXOP3 _ | INFIXOP4 _
+ | PLUS | MINUS | MINUSDOT | STAR | LESS | GREATER
+ | OR | BARBAR | AMPERSAND | AMPERAMPER | COLONEQUAL ->
+ may_start (next_token ())
+ | OPEN ->
+ begin match next_token () with
+ | UIDENT m, _, _ ->
+ List.iter
+ ~f:(fun (set,r) -> if List.mem m ~set then r := Some false)
+ [stdlabels, openstd; ["Unix"], openunix; morelabels, openmore]
+ | _ -> ()
+ end;
+ search_start (next_token ())
+ | _ ->
+ search_start (next_token ())
+
+ and process_paren (token, s, e) =
+ try match token with
+ LPAREN | LBRACKET | LBRACKETBAR | LBRACKETLESS | BEGIN ->
+ may_start (next_token ())
+ | LBRACE | LBRACELESS | STRUCT | SIG | OBJECT ->
+ search_start (next_token ())
+ | _ ->
+ assert false
+ with Closing last ->
+ match token, last with
+ LPAREN, RPAREN
+ | (LBRACKET|LBRACKETBAR|LBRACKETLESS),
+ (RBRACKET|BARRBRACKET|GREATERRBRACKET)
+ | (BEGIN|STRUCT|SIG|OBJECT), END
+ | LBRACE, RBRACE
+ | LBRACELESS, GREATERRBRACE -> ()
+ | _ -> raise (Closing last)
+ in
+ let first = next_token () in
+ try
+ if !alllabels then may_discard first else may_start first
+ with End_of_file ->
+ copy_input (Buffer.length input_buffer);
+ if not !alllabels
+ && List.exists (fun r -> !r = Some true) [openstd; openunix; openmore]
+ then begin
+ modified := true;
+ let text = Buffer.contents output_buffer in
+ Buffer.clear output_buffer;
+ let (token, s, _) = first in
+ Buffer.add_substring output_buffer text 0 s;
+ List.iter ~f:
+ (fun (r, s) ->
+ if !r = Some true then Buffer.add_string output_buffer s)
+ [ openstd, "open StdLabels\n"; openmore, "open MoreLabels\n";
+ openunix, "module Unix = UnixLabels\n" ];
+ let sep =
+ if List.mem token [CLASS; EXTERNAL; EXCEPTION; FUNCTOR; LET;
+ MODULE; FUNCTOR; TYPE; VAL]
+ then "\n"
+ else if token = OPEN then "" else ";;\n\n"
+ in
+ Buffer.add_string output_buffer sep;
+ Buffer.add_substring output_buffer text s (String.length text - s)
+ end
+ | Closing _ ->
+ prerr_endline ("bad closing token at position " ^
+ string_of_int (Lexing.lexeme_start buffer));
+ modified := false
+
+type state = Out | Enter | In | Escape
+
+let convert_intf buffer =
+ let input_pos = ref 0 in
+ let copy_input stop =
+ Buffer.add_substring output_buffer (Buffer.contents input_buffer)
+ !input_pos (stop - !input_pos);
+ input_pos := stop
+ in
+ let last = ref (EOF, 0, 0) in
+ let state = ref Out in
+ try while true do
+ let token = Lexer301.token buffer
+ and start = Lexing.lexeme_start buffer
+ and stop = Lexing.lexeme_end buffer
+ and last_token, last_start, last_stop = !last in
+ begin match token with
+ | EXCEPTION | CONSTRAINT ->
+ state := In
+ | VAL | EXTERNAL | CLASS | METHOD | TYPE | AND ->
+ state := Enter
+ | EQUAL when !state = Enter ->
+ state := In
+ | COLON ->
+ begin match !state, last_token with
+ | In, LIDENT _ ->
+ modified := true;
+ copy_input last_start;
+ input_pos := stop
+ | Enter, _ ->
+ state := In
+ | Escape, _ ->
+ state := In
+ | _ ->
+ state := Out
+ end
+ | LBRACE | SEMI | QUESTION when !state = In ->
+ state := Escape
+ | SEMISEMI | SIG | STRUCT | END | OBJECT | OPEN | INCLUDE | MODULE ->
+ state := Out
+ | EOF -> raise End_of_file
+ | _ -> ()
+ end;
+ last := (token, start, stop)
+ done with
+ End_of_file ->
+ copy_input (Buffer.length input_buffer)
+
+let convert_file ~intf name =
+ let ic = open_in name in
+ Buffer.clear input_buffer;
+ Buffer.clear output_buffer;
+ modified := false;
+ begin
+ let convert = if intf then convert_intf else convert_impl in
+ try convert (Lexing.from_function (input_function ic)); close_in ic
+ with exn -> close_in ic; raise exn
+ end;
+ if !modified then begin
+ let backup = name ^ ".bak" in
+ if Sys.file_exists backup then Sys.remove name
+ else Sys.rename name backup;
+ let oc = open_out name in
+ Buffer.output_buffer oc output_buffer;
+ close_out oc
+ end
+ else prerr_endline ("No changes in " ^ name)
+
+let _ =
+ let files = ref [] and intf = ref false
+ and keepstd = ref false and keepmore = ref false in
+ Arg.parse
+ [ "-intf", Arg.Set intf,
+ " remove all non-optional labels from an interface;\n" ^
+ " other options are ignored";
+ "-all", Arg.Set alllabels,
+ " remove all labels, possibly including optional ones!";
+ "-keepstd", Arg.Set keepstd,
+ " keep labels for Array, List, String and Unix";
+ "-keepmore", Arg.Set keepmore,
+ " keep also labels for Hashtbl, Map and Set; implies -keepstd";
+ "-m", Arg.String (fun s -> modules := s :: !modules),
+ "<module> remove also labels for <module>";
+ "-noopen", Arg.Set noopen,
+ " do not insert `open' statements for -keepstd/-keepmore" ]
+ (fun s -> files := s :: !files)
+ ("Usage: scrapelabels <options> <source files>\n" ^
+ " Remove labels from function arguments in standard library modules.\n" ^
+ " With -intf option below, can also process interfaces.\n" ^
+ " Old files are renamed to <file>.bak if there is no backup yet.\n" ^
+ "Options are:");
+ if !keepmore then keepstd := true;
+ if not !keepstd then modules := "Unix" :: stdlabels @ !modules;
+ if not !keepmore then modules := morelabels @ !modules;
+ List.iter (List.rev !files) ~f:
+ begin fun name ->
+ prerr_endline ("Processing " ^ name);
+ Printexc.catch (convert_file ~intf:!intf) name
+ end