1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module dextool.plugin.compiledb.frontend; 11 12 import std.algorithm : joiner; 13 import std.array : array; 14 import std.exception; 15 16 import logger = std.experimental.logger; 17 18 import dextool.compilation_db : CompileCommandDB, CompileCommandFilter, 19 defaultCompilerFilter, parseFlag, fromArgCompileDb, toString; 20 import dextool.type : AbsolutePath, ExitStatusType, FileName; 21 22 ExitStatusType doCompileDb(T)(ref T args) /*nothrow*/ { 23 CompileCommandDB compile_db; 24 try { 25 compile_db = args.inCompileDb.fromArgCompileDb; 26 } 27 catch (ErrnoException ex) { 28 logger.error(ex.msg); 29 return ExitStatusType.Errors; 30 } 31 32 debug logger.trace(compile_db.toString); 33 34 auto out_db = makeOutputFilename(args.out_); 35 writeDb(compile_db, out_db); 36 37 return ExitStatusType.Ok; 38 } 39 40 AbsolutePath makeOutputFilename(string out_) { 41 import std.file : isDir, FileException; 42 import std.path : buildPath; 43 44 try { 45 if (out_.isDir) { 46 return AbsolutePath(FileName(buildPath(out_, "compile_commands.json"))); 47 } 48 } 49 catch (FileException ex) { 50 } 51 52 return AbsolutePath(FileName(out_)); 53 } 54 55 void writeDb(ref CompileCommandDB db, AbsolutePath dst) { 56 import std.stdio : File; 57 58 auto fout = File(dst, "w"); 59 60 auto flag_filter = CompileCommandFilter(defaultCompilerFilter.filter.dup, 0); 61 logger.trace(flag_filter); 62 63 void writeEntry(T)(ref const T e) { 64 import std.exception : assumeUnique; 65 import std.json : JSONValue; 66 import std.utf : byChar; 67 68 string raw_flags = assumeUnique(e.parseFlag(flag_filter).flags.joiner(" ").byChar.array()); 69 70 fout.writefln(` "directory": "%s",`, cast(string) e.directory); 71 72 if (e.arguments.hasValue) { 73 fout.writefln(` "command": "g++ %s",`, raw_flags); 74 fout.writefln(` "arguments": "%s",`, raw_flags); 75 } else { 76 fout.writefln(` "command": "%s",`, raw_flags); 77 } 78 79 if (e.output.hasValue) 80 fout.writefln(` "output": "%s",`, cast(string) e.absoluteOutput); 81 fout.writefln(` "file": "%s"`, cast(string) e.absoluteFile); 82 } 83 84 if (db.length == 0) { 85 return; 86 } 87 88 fout.writeln("["); 89 90 foreach (ref const e; db[0 .. $ - 1]) { 91 fout.writeln(" {"); 92 writeEntry(e); 93 fout.writeln(" },"); 94 } 95 96 fout.writeln(" {"); 97 writeEntry(db[$ - 1]); 98 fout.writeln(" }"); 99 100 fout.writeln("]"); 101 }