Skip to content
Snippets Groups Projects
Commit 8d11b760 authored by Valentin Perrelle's avatar Valentin Perrelle
Browse files

Merge branch 'feature/andre/scripts-export-framac-dir' into 'master'

[analysis-scripts] export FRAMAC_BIN from frama-c-script and update scripts

See merge request frama-c/frama-c!2793
parents e9b4bef1 5fe84d36
No related branches found
No related tags found
No related merge requests found
...@@ -85,6 +85,9 @@ if [ $# -lt 1 ]; then ...@@ -85,6 +85,9 @@ if [ $# -lt 1 ]; then
fi fi
DIR="$( cd "$( dirname "$0" )" && pwd )" DIR="$( cd "$( dirname "$0" )" && pwd )"
# All scripts called by frama-c-script may rely on FRAMAC_BIN pointing to the
# directory containing frama-c, frama-c-config and frama-c-script.
export FRAMAC_BIN="$DIR"
FRAMAC_SHARE=$("${DIR}/frama-c-config" -share) FRAMAC_SHARE=$("${DIR}/frama-c-config" -share)
if [ -z ${FRAMAC_SESSION+x} ]; then if [ -z ${FRAMAC_SESSION+x} ]; then
FRAMAC_SESSION="./.frama-c"; FRAMAC_SESSION="./.frama-c";
...@@ -137,12 +140,12 @@ make_path() { ...@@ -137,12 +140,12 @@ make_path() {
esac esac
fi fi
cat <<EOF > "${dir}/path.mk" cat <<EOF > "${dir}/path.mk"
FRAMAC_DIR=${DIR} FRAMAC_BIN=${DIR}
ifeq (\$(wildcard \$(FRAMAC_DIR)),) ifeq (\$(wildcard \$(FRAMAC_BIN)),)
# Frama-C not installed locally; using the version in the PATH # Frama-C not installed locally; using the version in the PATH
else else
FRAMAC=\$(FRAMAC_DIR)/frama-c FRAMAC=\$(FRAMAC_BIN)/frama-c
FRAMAC_GUI=\$(FRAMAC_DIR)/frama-c-gui FRAMAC_GUI=\$(FRAMAC_BIN)/frama-c-gui
endif endif
EOF EOF
echo "Wrote to: ${dir}/path.mk" echo "Wrote to: ${dir}/path.mk"
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
# This script finds files containing likely declarations and definitions # This script finds files containing likely declarations and definitions
# for a given function name, via heuristic syntactic matching. # for a given function name, via heuristic syntactic matching.
import argparse
import sys import sys
import os import os
import re import re
...@@ -35,37 +36,38 @@ MIN_PYTHON = (3, 5) # for glob(recursive) ...@@ -35,37 +36,38 @@ MIN_PYTHON = (3, 5) # for glob(recursive)
if sys.version_info < MIN_PYTHON: if sys.version_info < MIN_PYTHON:
sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON) sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON)
debug = False parser = argparse.ArgumentParser(description="""
Looks for likely declarations/definitions of a function
in files with extensions '.c', '.h' and '.i'.
If any directories are specified, looks inside them,
otherwise looks inside PWD and /usr/include.
Subdirectories are always considered recursively.""")
arg = "" parser.add_argument('--directory', '-C', metavar='DIR', default=".", nargs=1,
if len(sys.argv) < 2: help='print paths relative to directory DIR (default: .)')
print("usage: %s fname [dir1 dir2 ...]" % sys.argv[0]) parser.add_argument('funcname', help='function name to search')
print(" looks for likely declarations/definitions of function fname") parser.add_argument('dir', nargs='*', help='directories where to search (if empty: PWD /usr/include)')
print(" in files with extensions '.c', '.h' and '.i';") args = vars(parser.parse_args())
print(" if dir1, dir2, etc, are specified, looks inside them,")
print(" otherwise looks inside PWD and /usr/include.")
print(" Subdirectories are always considered recursively.")
sys.exit(1)
else:
fname = sys.argv[1]
if re.match('[a-zA-Z_][a-zA-Z0-9_]*$', fname) == None:
print("error: function name contains invalid characters: %s" % fname)
print(" (only letters/digits/underscore allowed)")
sys.exit(1)
dirs = set() reldir = args["directory"][0]
if len(sys.argv) < 3: fname = args["funcname"]
pwd = os.getcwd() dirs = args["dir"]
dirs = [pwd, "/usr/include"]
else:
dirs = set(sys.argv[2:])
if debug: if re.match('[a-zA-Z_][a-zA-Z0-9_]*$', fname) == None:
print("Looking for files in dirs (and their subdirs): %s" % dirs) print("error: function name contains invalid characters: %s" % fname)
print(" (only letters/digits/underscore allowed)")
sys.exit(1)
dirs = set(dirs)
if not dirs:
pwd = os.getcwd()
dirs = [pwd, "/usr/include"]
else:
dirs = set(sys.argv[2:])
files = [] files = []
for d in dirs: for d in dirs:
files += glob.glob(d + "/**/*.[ich]", recursive=True) files += glob.glob(d + "/**/*.[ich]", recursive=True)
print("Looking for '%s' inside %d file(s)..." % (fname, len(files))) print("Looking for '%s' inside %d file(s)..." % (fname, len(files)))
...@@ -80,14 +82,20 @@ for f in files: ...@@ -80,14 +82,20 @@ for f in files:
else: else:
possible_definers.append(f) possible_definers.append(f)
def relative_path_to(start):
return lambda p: os.path.relpath(p, start=start)
if possible_declarators == [] and possible_definers == []: if possible_declarators == [] and possible_definers == []:
print("No declaration/definition found for function '%s'" % fname) print("No declaration/definition found for function '%s'" % fname)
else: else:
if possible_declarators != []: if reldir != ".":
print("Possible declarations for function '%s' in the following file(s):" reldir_msg = f" (relative to '{reldir}')"
% fname) else:
print(" " + "\n ".join(map(os.path.relpath, possible_declarators))) reldir_msg = ""
if possible_definers != []: relative_path = relative_path_to(reldir)
print("Possible definitions for function '%s' in the following file(s):" if possible_declarators != []:
% fname) print(f"Possible declarations for function '{fname}' in the following file(s){reldir_msg}:")
print(" " + "\n ".join(map(os.path.relpath, possible_definers))) print(" " + "\n ".join([os.path.relpath(path, start=reldir) for path in possible_declarators]))
if possible_definers != []:
print(f"Possible definitions for function '{fname}' in the following file(s){reldir_msg}:")
print(" " + "\n ".join([os.path.relpath(path, start=reldir) for path in possible_definers]))
...@@ -26,25 +26,33 @@ ...@@ -26,25 +26,33 @@
# GNUmakefile template): it parses the output and suggests useful commands # GNUmakefile template): it parses the output and suggests useful commands
# whenever it can, by calling frama-c-script itself. # whenever it can, by calling frama-c-script itself.
import subprocess import argparse
import sys
import os import os
import re import re
import subprocess
import sys
from functools import partial from functools import partial
if len(sys.argv) < 3: MIN_PYTHON = (3, 6) # for automatic Path conversions
print("usage: %s path-to-frama-c-script target" % sys.argv[0]) if sys.version_info < MIN_PYTHON:
print(" Builds the specified target, parsing the output to") sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON)
print(" identify and recommend actions in case of failure.")
print(" The first argument must be the path to the frama-c-script") parser = argparse.ArgumentParser(description="""
print(" binary.") Builds the specified target, parsing the output to identify and recommend
sys.exit(1) actions in case of failure.""")
parser.add_argument('--make-dir', metavar='DIR', default=".frama-c", nargs=1,
help='directory containing the makefile (default: .frama-c)')
(make_dir_arg, args) = parser.parse_known_args()
make_dir = vars(make_dir_arg)["make_dir"]
args = args[1:]
framac_script = sys.argv[1] framac_bin = os.getenv('FRAMAC_BIN')
target = sys.argv[2] if not framac_bin:
args = sys.argv[3:] sys.exit("error: FRAMAC_BIN not in environment")
framac_script = f"{framac_bin}/frama-c-script"
out = subprocess.Popen(['make', target] + args, out = subprocess.Popen(['make', "-C", make_dir] + args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = out.communicate()[0].decode('utf-8') output = out.communicate()[0].decode('utf-8')
...@@ -62,7 +70,7 @@ for line in lines: ...@@ -62,7 +70,7 @@ for line in lines:
if match: if match:
fname = match.group(1) fname = match.group(1)
def action(fname): def action(fname):
out = subprocess.Popen([framac_script, "find-fun", fname], out = subprocess.Popen([framac_script, "find-fun", "-C", make_dir, fname],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = out.communicate()[0].decode('utf-8') output = out.communicate()[0].decode('utf-8')
re_possible_definers = re.compile("Possible definitions for function") re_possible_definers = re.compile("Possible definitions for function")
......
...@@ -45,7 +45,7 @@ def build_make_environment(framac): ...@@ -45,7 +45,7 @@ def build_make_environment(framac):
else: else:
env = { **os.environ, 'PATH' : f"{framac}/bin:{os.environ['PATH']}" } env = { **os.environ, 'PATH' : f"{framac}/bin:{os.environ['PATH']}" }
args = [ args = [
f"FRAMAC_DIR={framac}/bin", f"FRAMAC_BIN={framac}/bin",
f"FRAMAC={framac}/bin/frama-c" f"FRAMAC={framac}/bin/frama-c"
] ]
return env, args return env, args
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment