summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2019-08-10 14:27:55 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2020-11-17 10:04:13 -0800
commit8bc1092f41741a3ef1de9d360cd98ccb3b317962 (patch)
tree4cfed3fbe80c6991d362c7d8f8ab64191f2b5b71
parent3637b611a7c4bf83a55dbf8c13f492234686b787 (diff)
downloadspack-8bc1092f41741a3ef1de9d360cd98ccb3b317962.tar.gz
spack-8bc1092f41741a3ef1de9d360cd98ccb3b317962.tar.bz2
spack-8bc1092f41741a3ef1de9d360cd98ccb3b317962.tar.xz
spack-8bc1092f41741a3ef1de9d360cd98ccb3b317962.zip
concretizer: colorize ASP output
-rw-r--r--lib/spack/spack/solver/asp.py53
1 files changed, 46 insertions, 7 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 30268e5224..55bf38ec50 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -13,6 +13,7 @@ import types
from six import string_types
import llnl.util.tty as tty
+import llnl.util.tty.color as color
import spack
import spack.cmd
@@ -386,6 +387,37 @@ class Result(object):
self.answers = []
+def highlight(string):
+ """Syntax highlighting for ASP programs"""
+ # variables
+ string = re.sub(r'\b([A-Z])\b', r'@y{\1}', string)
+
+ # implications
+ string = re.sub(r':-', r'@*G{:-}', string)
+
+ # final periods
+ string = re.sub(r'^([^%].*)\.$', r'\1@*G{.}', string, flags=re.MULTILINE)
+
+ # directives
+ string = re.sub(
+ r'(#\w*)( (?:\w*)?)((?:/\d+)?)', r'@*B{\1}@c{\2}\3', string)
+
+ # functions
+ string = re.sub(r'(\w[\w-]+)\(([^)]*)\)', r'@C{\1}@w{(}\2@w{)}', string)
+
+ # comments
+ string = re.sub(r'(%.*)$', r'@K\1@.', string, flags=re.MULTILINE)
+
+ # strings
+ string = re.sub(r'("[^"]*")', r'@m{\1}', string)
+
+ # result
+ string = re.sub(r'\bUNSATISFIABLE', "@R{UNSATISFIABLE}", string)
+ string = re.sub(r'\bINCONSISTENT', "@R{INCONSISTENT}", string)
+ string = re.sub(r'\bSATISFIABLE', "@G{SATISFIABLE}", string)
+
+ return string
+
#
# These are handwritten parts for the Spack ASP model.
#
@@ -400,6 +432,9 @@ def solve(specs, dump=None, models=1):
clingo = which('clingo', required=True)
parser = ResultParser()
+ def colorize(string):
+ color.cprint(highlight(color.cescape(string)))
+
with tempfile.TemporaryFile("w+") as program:
generator = AspGenerator(program)
generator.generate_asp_program(specs)
@@ -409,8 +444,9 @@ def solve(specs, dump=None, models=1):
program.seek(0)
if 'asp' in dump:
- tty.msg('ASP program:')
- sys.stdout.write(result.asp)
+ if sys.stdout.isatty():
+ tty.msg('ASP program:')
+ colorize(result.asp)
with tempfile.TemporaryFile("w+") as output:
with tempfile.TemporaryFile() as warnings:
@@ -427,18 +463,21 @@ def solve(specs, dump=None, models=1):
# dump any warnings generated by the solver
if 'warnings' in dump:
if result.warnings:
- tty.msg('Clingo gave the following warnings:')
- sys.stdout.write(result.warnings)
+ if sys.stdout.isatty():
+ tty.msg('Clingo gave the following warnings:')
+ colorize(result.warnings)
else:
- tty.msg('No warnings.')
+ if sys.stdout.isatty():
+ tty.msg('No warnings.')
output.seek(0)
result.output = output.read()
# dump the raw output of the solver
if 'output' in dump:
- tty.msg('Clingo output:')
- sys.stdout.write(result.output)
+ if sys.stdout.isatty():
+ tty.msg('Clingo output:')
+ colorize(result.output)
output.seek(0)
parser.parse(output, result)