OCAMLDOCFLAGS = -html -sort
+SUBDIRS =
+ifneq ($(pkg_cil),no)
+SUBDIRS += cil-tools
+endif
+
EXAMPLES = $(patsubst %.ml,%,$(wildcard examples/*.ml))
TESTS = $(patsubst %.ml,%,$(wildcard tests/*.ml))
all: bitmatch.cma bitmatch.cmxa pa_bitmatch.cmo
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
bitmatch.cma: bitmatch_types.cmo bitmatch_config.cmo bitmatch.cmo
$(OCAMLFIND) ocamlc -a -o $@ $^
$$f; \
if [ $$? -ne 0 ]; then exit 1; fi; \
done
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
examples: pa_bitmatch.cmo bitmatch.cma
@for f in $(EXAMPLES); do \
-package unix -linkpkg -I . bitmatch.cma $$f.ml -o $$f; \
if [ $$? -ne 0 ]; then exit 1; fi; \
done
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
print-tests: pa_bitmatch.cmo
@for f in $(TESTS); do \
rm -f core *~ *.cmi *.cmo *.cmx *.cma *.cmxa *.a *.o
rm -f tests/*~ tests/*.cmi tests/*.cmo $(TESTS)
rm -f examples/*~ examples/*.cmi examples/*.cmo $(EXAMPLES)
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
distclean: clean
rm -rf autom4te.cache
rm -f config.log config.status
rm -f config.h Makefile META bitmatch_config.ml
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
# Documentation.
ocamlfind install bitmatch META *.mli *.cmx *.cma *.cmxa *.a \
bitmatch.cmi \
pa_bitmatch.cmo
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
# Standard rules.
$(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTPACKAGES) -c $<
depend: .depend
+ @for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
.depend: bitmatch.ml bitmatch.mli
rm -f .depend
Please see the html subdirectory for developer documentation.
-The only dependencies are OCaml >= 3.10.0, camlp4, ocamldoc, and findlib.
+The only requirements are OCaml >= 3.10.0, camlp4, ocamldoc, and findlib.
+
+If you optionally have CIL (http://cil.sourceforge.net/) installed
+then there are some nice extra tools for converting C header files
+into matchable OCaml structures.
To build:
--- /dev/null
+bitmatch_import_c.cmo: ../bitmatch.cmi
+bitmatch_import_c.cmx: ../bitmatch.cmx
--- /dev/null
+# Bitmatch syntax extension.
+# Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# $Id: Makefile.in 81 2008-05-21 09:59:21Z richard.wm.jones $
+
+PACKAGE = @PACKAGE_NAME@
+VERSION = @PACKAGE_VERSION@
+
+OCAMLFIND = @OCAMLFIND@
+OCAMLMKLIB = @OCAMLMKLIB@
+OCAMLDOC = @OCAMLDOC@
+INSTALL = @INSTALL@
+
+OCAMLCFLAGS = -g
+OCAMLCPACKAGES = -package unix,str,extlib,cil -I ..
+OCAMLCLIBS = $(OCAMLCPACKAGES) -linkpkg ../bitmatch.cma
+OCAMLOPTFLAGS =
+OCAMLOPTPACKAGES = $(OCAMLCPACKAGES)
+OCAMLOPTLIBS = $(OCAMLOPTPACKAGES) -linkpkg ../bitmatch.cmxa
+
+OCAMLDOCFLAGS = -html -sort
+
+all: bitmatch-import-c bitmatch-import-c.opt
+
+bitmatch-import-c: bitmatch_import_c.cmo
+ $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCLIBS) $< -o $@
+
+bitmatch-import-c.opt: bitmatch_import_c.cmx
+ $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) $< -o $@
+
+test:
+
+examples:
+
+# Clean.
+
+clean:
+ rm -f core *~ *.cmi *.cmo *.cmx *.cma *.cmxa *.a *.o
+
+distclean: clean
+
+# Install.
+
+install:
+
+# Standard rules.
+
+.mli.cmi:
+ $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCPACKAGES) -c $<
+.ml.cmo:
+ $(OCAMLFIND) ocamlc $(OCAMLCFLAGS) $(OCAMLCPACKAGES) -c $<
+.ml.cmx:
+ $(OCAMLFIND) ocamlopt $(OCAMLOPTFLAGS) $(OCAMLOPTPACKAGES) -c $<
+
+depend: .depend
+
+.depend: $(wildcard *.ml) $(wildcard *.mli)
+ rm -f .depend
+ $(OCAMLFIND) ocamldep $(OCAMLCPACKAGES) $^ > $@
+
+ifeq ($(wildcard .depend),.depend)
+include .depend
+endif
+
+.PHONY: depend dist check-manifest dpkg doc \
+ print-examples print-tests examples test
+
+.SUFFIXES: .cmo .cmi .cmx .ml .mli .mll
--- /dev/null
+/* This file is automagically prefixed to all .ubd files
+ * and provides some macros that we need for CIL.
+ */
+
+#define BITMATCH_IMPORT(name) __bitmatch_import_##name
+#define BITMATCH_CONSTANT_STRING(name,val) \
+ char *__bitmatch_constant_##name = val
+#define BITMATCH_CONSTANT_INT32(name,val) \
+ int __bitmatch_constant_##name = val
--- /dev/null
+(* Import a C header file.
+ * Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * $Id$
+ *)
+
+open Printf
+open ExtList
+open ExtString
+open Cil
+
+let () =
+ (* Parse command line arguments. *)
+ let debug = ref false in
+ let save_temps = ref false in
+ let version () =
+ printf "bitmatch-import-c %s" Bitmatch.version;
+ exit 1
+ in
+
+ let argspec = Arg.align [
+ "--debug", Arg.Set debug,
+ " Debug messages";
+ "-save-temps", Arg.Set save_temps,
+ " Save temporary files";
+ "--version", Arg.Unit version,
+ " Display version and exit";
+ ] in
+
+ let input_file = ref None in
+ let anon_fun str =
+ match !input_file with
+ | None -> input_file := Some str
+ | Some _ ->
+ eprintf "bitmatch-import-c: only give a single input file\n";
+ exit 1
+ in
+ let usage_msg = "\
+
+bitmatch-import-c: Import C structures and constants and
+ generate bitmatching functions from them. Please see the
+ manual page bitmatch-import-c(1) for more information.
+
+OPTIONS" in
+
+ Arg.parse argspec anon_fun usage_msg;
+
+ let debug = !debug in
+ let save_temps = !save_temps in
+ let input_file =
+ match !input_file with
+ | Some f -> f
+ | None ->
+ eprintf "bitmatch-import-c: no input file specified\n";
+ exit 1 in
+
+ (* Grab the file and pass it to the preprocessor, and then read the
+ * C code into memory using CIL.
+ *)
+ msvcMode := false;
+ Cil.initCIL ();
+
+ (* XXX Unavoidable tmp exploit here. Fix? *)
+ let tmp, delete_tmp =
+ if not save_temps then (
+ let tmp = Filename.temp_file (Filename.temp_dir_name) ".i" in
+ tmp, fun () -> try Unix.unlink tmp with Unix.Unix_error _ -> ()
+ ) else (
+ let tmp = Filename.chop_extension input_file ^ ".i" in
+ tmp, fun () -> (* -save-temps, so do nothing *) ()
+ ) in
+
+ let cmd =
+ sprintf "cpp -include bitmatch-import-prefix.h %s > %s"
+ (Filename.quote input_file) (Filename.quote tmp) in
+ if debug then prerr_endline cmd;
+ if Sys.command cmd <> 0 then (
+ eprintf "%s: command failed\n" cmd;
+ delete_tmp ();
+ exit 1
+ );
+
+ (* Why does Frontc.parse return a continuation ...? *)
+ let file = (Frontc.parse tmp) () in
+ delete_tmp ();
+
+ (* Find out which structures, #defines, etc. are to be imported.
+ * (cf. the macros in bitmatch-import-prefix.h)
+ *)
+ let constants =
+ List.filter_map (
+ function
+ | GVar ({vname = vname; vtype = vtype},
+ { init = Some (SingleInit vinit) },
+ loc)
+ when String.starts_with vname "__bitmatch_constant_" ->
+ let vname = String.sub vname 20 (String.length vname - 20) in
+
+ (* Do constant folding on the initializer and then calculate
+ * its compile-time value.
+ *)
+ let vinit =
+ match isInteger (constFold true vinit) with
+ | Some i -> i
+ | None ->
+ Errormsg.error
+ "%a: non-constant initializer: %a" d_loc loc d_exp vinit;
+ -1L in
+
+ Some (vname, vinit, loc)
+ | _ -> None
+ ) file.globals in
+ let structs =
+ List.filter_map (
+ function
+ | GType ({tname = tname; ttype = ttype}, loc)
+ when String.starts_with tname "__bitmatch_import_" ->
+ let tname = String.sub tname 18 (String.length tname - 18) in
+ Some (tname, ttype, loc)
+ | _ -> None
+ ) file.globals in
+
+ if !Errormsg.hadErrors then exit 1;
+
+ (* If debugging, print out the imports. *)
+ if debug then (
+ List.iter (
+ fun (vname, vinit, loc) ->
+ Errormsg.log "%a: import %s as constant 0x%LX\n" d_loc loc vname vinit;
+ ) constants;
+ List.iter (
+ fun (tname, ttype, loc) ->
+ Errormsg.log "%a: import %s as %a\n" d_loc loc tname d_type ttype;
+ ) structs;
+ );
+
--- /dev/null
+/* This is an example import file, showing how to import the ext3
+ * superblock automatically from Linux header files.
+ *
+ * Use: bitmatch-import-c ext3.c
+ *
+ * Tip: Add the --debug flag to that command line to see what's going on.
+ */
+
+/* These are required by Linux in order to get the little/big-endian
+ * notations present in the Linux kernel header files. Any other
+ * defines needed can go here.
+ */
+#define __CHECKER__ 1
+#define __CHECK_ENDIAN__ 1
+
+/* Include files necessary to get the structure(s) and constant(s) we're
+ * interested in.
+ */
+#include <linux/magic.h>
+#include <linux/ext3_fs.h>
+
+/* This tells the importer program what structures and constants to import. */
+typedef struct ext3_super_block BITMATCH_IMPORT(ext3_super_block);
+BITMATCH_CONSTANT_INT32 (ext3_super_magic, EXT3_SUPER_MAGIC);
AC_PROG_CC_C_O
-dnl Check for endianness.
+dnl Check for native endianness.
AC_C_BIGENDIAN(
[NATIVEENDIAN=BigEndian],
[NATIVEENDIAN=LittleEndian],
AC_MSG_ERROR([You must have camlp4 installed])
fi
+dnl Check for CIL (optional)
+AC_CHECK_OCAML_PKG(cil)
+AC_SUBST(pkg_cil)
+
dnl Produce output files.
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile META bitmatch_config.ml])
+AC_CONFIG_FILES([Makefile META bitmatch_config.ml cil-tools/Makefile])
AC_OUTPUT