diff --git a/infer/src/Makefile b/infer/src/Makefile index 208180b70..8a0e96fc7 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -49,6 +49,13 @@ ifneq (,$(findstring s,$(MAKEFLAGS))) OCAMLBUILD_OPTIONS += -quiet endif + +#### Base declaration #### + +C_STUBS_SOURCE = stubs/c/stubs.c +# only one C object for now, the Makefile will need changing if more are added +C_STUBS_OBJ = $(C_STUBS_SOURCE:.c=.o) + #### Backend declarations #### INFER_MAIN = backend/infer @@ -138,8 +145,13 @@ OCAMLBUILD_BASE = rebuild $(OCAMLBUILD_OPTIONS) -j $(NCPU) $(addprefix -I , $(DE # ocamlbuild with options necessary to build all targets at once, regardless of configure flags OCAMLBUILD_ALL = $(OCAMLBUILD_BASE) $(JAVA_OCAMLBUILD_OPTIONS) +OCAMLBUILD_BYTE_OPTS = -lflags -custom,$(C_STUBS_OBJ) -I stubs/c + +OCAMLBUILD_NATIVE_OPTS = -lflags $(C_STUBS_OBJ) -I stubs/c + # list of ocamlbuild targets common to all build targets -- native version INFER_BASE_TARGETS = \ + $(C_STUBS_OBJ) \ $(INFER_MAIN).native \ $(INFERANALYZE_MAIN).native \ $(INFERPRINT_MAIN).native \ @@ -173,7 +185,8 @@ endif all: infer infer: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) - $(OCAMLBUILD_CONFIG) -build-dir $(INFER_BUILD_DIR) $(INFER_CONFIG_TARGETS) + $(OCAMLBUILD_CONFIG) -build-dir $(INFER_BUILD_DIR) $(OCAMLBUILD_NATIVE_OPTS) \ + $(INFER_CONFIG_TARGETS) $(COPY) $(INFER_BUILD_DIR)/$(INFER_MAIN).native $(INFER_BIN) $(COPY) $(INFER_BUILD_DIR)/$(INFERANALYZE_MAIN).native $(INFERANALYZE_BIN) $(COPY) $(INFER_BUILD_DIR)/$(INFERPRINT_MAIN).native $(INFERPRINT_BIN) @@ -196,7 +209,8 @@ infer: $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) $(CLANG_BINIOU_DI endif byte: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) - $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) $(INFER_ALL_TARGETS:.native=.byte) + $(OCAMLBUILD_ALL) $(OCAMLBUILD_BYTE_OPTS) -build-dir $(INFER_BUILD_DIR) \ + $(INFER_ALL_TARGETS:.native=.byte) # to build only the single module (and its dependencies) with extra flags execute: # make MFLAGS= M=.cm{o,x} module @@ -211,7 +225,7 @@ module: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN $(M) test_build: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) - $(OCAMLBUILD_ALL) -build-dir $(TEST_BUILD_DIR) \ + $(OCAMLBUILD_ALL) $(OCAMLBUILD_BYTE_OPTS) -build-dir $(TEST_BUILD_DIR) \ -cflags -warn-error,$(OCAML_FATAL_WARNINGS) \ $(INFER_ALL_TARGETS:.native=.byte) @@ -234,7 +248,7 @@ roots:=Infer InferAnalyze InferClang CMain JMain InferPrint BuckCompilationDatab clusters:=base clang java IR src_dirs:=$(shell find * -type d) -ml_src_files:=$(shell find $(src_dirs) -regex '.*\.ml\(i\)*' -not -path facebook/scripts/eradicate_stats.ml) +ml_src_files:=$(shell find $(src_dirs) -regex '.*\.ml\(i\)*' -not -path facebook/scripts/eradicate_stats.ml -not -path 'stubs/c/*') re_src_files:=$(shell find $(src_dirs) -regex '.*\.re\(i\)*') inc_flags:=$(foreach dir,$(src_dirs),-I $(dir)) root_flags:=$(foreach root,$(roots),-r $(root)) @@ -251,7 +265,7 @@ mod_dep.pdf: mod_dep.dot dot -Tpdf -o mod_dep.pdf mod_dep.dot roots_grep_regex:=$(foreach root,$(roots),-e $(root)$$) -dirs_find_regex:=$(foreach dir, $(DEPENDENCIES),-path "./$(dir)/*" -o) +dirs_find_regex:=$(foreach dir, $(DEPENDENCIES) stubs/ml,-path "./$(dir)/*" -o) toplevel: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) # We need to pack all infer modules into another module to avoid name clashes # with some of them coming from ocaml libraries (Ident for example). @@ -269,7 +283,7 @@ toplevel: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDG | rev | cut -f 2- -d '.' | rev \ | awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}' \ | grep -v $(roots_grep_regex) > toplevel.mlpack - $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) toplevel.cmo + $(OCAMLBUILD_ALL) -I stubs/ml -build-dir $(INFER_BUILD_DIR) toplevel.cmo define gen_atdgen_rules # generate files using atdgen diff --git a/infer/src/base/CommandLineOption.ml b/infer/src/base/CommandLineOption.ml index 7f47e2655..8368cfa82 100644 --- a/infer/src/base/CommandLineOption.ml +++ b/infer/src/base/CommandLineOption.ml @@ -148,15 +148,9 @@ let pad_and_xform doc_width left_width desc = let align desc_list = let min_term_width = 80 in - (* Try to prevent `tput` from complaining about $TERM not being set as it pollutes stderr. We - cannot redirect stderr as `tput` needs access to the tty and we are already redirecting stdout - to read the result from `tput`. *) - (try Unix.getenv "TERM" |> ignore - with Not_found -> Unix.putenv "TERM" "ansi"); - let cur_term_width = try with_process_in "tput cols" input_line |> fst |> int_of_string - with - | End_of_file (* tput is unhappy *) - | Failure "int_of_string" (* not sure if possible *) -> min_term_width in + let cur_term_width = + (* `CStubs.term_width ()` return 0 in case of failure *) + max (CStubs.term_width ()) min_term_width in (* 2 blank columns before option + 2 columns of gap between flag and doc *) let extra_space = 4 in let min_left_width = 15 in diff --git a/infer/src/stubs/c/CStubs.ml b/infer/src/stubs/c/CStubs.ml new file mode 100644 index 000000000..4c304d709 --- /dev/null +++ b/infer/src/stubs/c/CStubs.ml @@ -0,0 +1,10 @@ +(* + * Copyright (c) 2016 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +external term_width : unit -> int = "term_width" diff --git a/infer/src/stubs/c/CStubs.mli b/infer/src/stubs/c/CStubs.mli new file mode 100644 index 000000000..4c304d709 --- /dev/null +++ b/infer/src/stubs/c/CStubs.mli @@ -0,0 +1,10 @@ +(* + * Copyright (c) 2016 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +external term_width : unit -> int = "term_width" diff --git a/infer/src/stubs/c/stubs.c b/infer/src/stubs/c/stubs.c new file mode 100644 index 000000000..013283a4f --- /dev/null +++ b/infer/src/stubs/c/stubs.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2016 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include + +CAMLprim value term_width(value unit) { + CAMLparam1(unit); + + struct winsize sz; + + int size = 0; + if (ioctl(0, TIOCGWINSZ, &sz) >= 0) { + size = sz.ws_col; + } + CAMLreturn(Val_int(size)); +} diff --git a/infer/src/stubs/ml/CStubs.ml b/infer/src/stubs/ml/CStubs.ml new file mode 100644 index 000000000..415ed13f4 --- /dev/null +++ b/infer/src/stubs/ml/CStubs.ml @@ -0,0 +1,15 @@ +(* + * Copyright (c) 2016 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +(** Reimplement C stubs in a simplified way to make it easier to build an Infer toplevel. This is + because we don't care about the exact implementation of the C stubs as far as the toplevel + goes. *) + + +let term_width () = 80 diff --git a/infer/src/stubs/ml/CStubs.mli b/infer/src/stubs/ml/CStubs.mli new file mode 100644 index 000000000..bee037265 --- /dev/null +++ b/infer/src/stubs/ml/CStubs.mli @@ -0,0 +1,10 @@ +(* + * Copyright (c) 2016 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +val term_width : unit -> int