Last active
November 1, 2016 05:29
-
-
Save fwyzard/727563d5fe7ebfb084f40392bdad019d to your computer and use it in GitHub Desktop.
Python tool to add entries to an LLVM compilation database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
import sys | |
import os | |
import fcntl | |
import argparse | |
import json | |
# the default location for the compilation database is the file 'compile_commands.json' in the current directory | |
def_dbname = 'compile_commands.json' | |
# arguments and options | |
parser = argparse.ArgumentParser( | |
description = '''Add an entry to an LLVM Compilation Database. | |
See http://clang.llvm.org/docs/JSONCompilationDatabase.html for details.''') | |
parser.add_argument('--path', '-p', | |
metavar = 'PATH', | |
dest = 'dbname', | |
default = def_dbname, | |
help = '''path to the compilation database (directory or json file). | |
PATH can be a file or directory; if it is a directory, PATH/compile_commands.json will be used. | |
The default is to use the file "compile_commands.json" in the current directory.''') | |
parser.add_argument('--replace', '-r', | |
action = 'store_true', | |
default = False, | |
help = 'replace any existing record with the same FILE entry. The default is to allow duplicates with a different COMMAND or DIRECTORY.') | |
parser.add_argument('--directory', '-d', | |
metavar = 'DIRECTORY', | |
default = os.getcwd(), | |
help = 'set the "directory" entry for the new record. The default is the current directory.') | |
parser.add_argument('file', | |
metavar = 'FILE', | |
help = 'set the "file" entry for the new record') | |
parser.add_argument('command', | |
metavar = 'COMMAND', | |
help = 'set the "command" entry for the new record') | |
args = parser.parse_args() | |
# open the file for read/append, so it is not truncated | |
dbname = args.dbname | |
if os.path.isdir(dbname): | |
dbname = os.path.join(dbname, def_dbname) | |
dbfile = open(dbname, 'a+') | |
# acquire an advisory exclusive lock on the file | |
fcntl.flock(dbfile, fcntl.LOCK_EX) | |
# read the content of the file | |
dbfile.seek(0) | |
dbjson = dbfile.read() | |
try: | |
dbdata = json.loads(dbjson) | |
except ValueError as e: | |
# if the file is empty or the content s not valid json, start from an empty database | |
dbdata = [] | |
# add the new record, if not present already | |
record = { 'directory': args.directory, 'file': args.file, 'command': args.command } | |
if args.replace: | |
for r in list(dbdata): | |
if r['file'] == record['file']: | |
dbdata.remove(r) | |
dbdata.append(record) | |
else: | |
if not record in dbdata: | |
dbdata.append(record) | |
# truncate the file and replace its content | |
dbfile.seek(0) | |
dbfile.truncate() | |
dbfile.write(json.dumps(dbdata, indent=2, separators=(',', ': '))) | |
dbfile.write('\n') | |
# the lock is automatically release when the file is closed | |
dbfile.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment