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 This is a handy range to interate over either all files from the user OR all 11 files in a compilation database. 12 */ 13 module dextool.user_filerange; 14 15 import dextool.compilation_db : CompileCommandFilter, CompileCommandDB, 16 parseFlag; 17 import dextool.type : FileName, AbsolutePath; 18 19 @safe: 20 21 struct UserFileRange { 22 import std.typecons : Nullable; 23 import dextool.clang : findFlags; 24 import dextool.compilation_db : SearchResult; 25 26 enum RangeOver { 27 inFiles, 28 database 29 } 30 31 this(CompileCommandDB db, string[] in_files, string[] cflags, 32 const CompileCommandFilter ccFilter) { 33 this.db = db; 34 this.cflags = cflags; 35 this.ccFilter = ccFilter; 36 this.inFiles = in_files; 37 38 if (in_files.length == 0) { 39 kind = RangeOver.database; 40 } else { 41 kind = RangeOver.inFiles; 42 } 43 } 44 45 const RangeOver kind; 46 CompileCommandDB db; 47 string[] inFiles; 48 string[] cflags; 49 const CompileCommandFilter ccFilter; 50 51 Nullable!SearchResult front() { 52 assert(!empty, "Can't get front of an empty range"); 53 54 Nullable!SearchResult curr; 55 56 final switch (kind) { 57 case RangeOver.inFiles: 58 if (db.length > 0) { 59 curr = db.findFlags(FileName(inFiles[0]), cflags, ccFilter); 60 } else { 61 curr = SearchResult(cflags.dup, AbsolutePath(FileName(inFiles[0]))); 62 } 63 break; 64 case RangeOver.database: 65 import std.array : appender; 66 67 auto tmp = db.payload[0]; 68 auto flags = appender!(string[])(); 69 flags.put(cflags); 70 flags.put(tmp.parseFlag(ccFilter)); 71 curr = SearchResult(flags.data, tmp.absoluteFile); 72 break; 73 } 74 75 return curr; 76 } 77 78 void popFront() { 79 assert(!empty, "Can't pop front of an empty range"); 80 81 final switch (kind) { 82 case RangeOver.inFiles: 83 inFiles = inFiles[1 .. $]; 84 break; 85 case RangeOver.database: 86 db.payload = db.payload[1 .. $]; 87 break; 88 } 89 } 90 91 bool empty() @safe pure nothrow const @nogc { 92 final switch (kind) { 93 case RangeOver.inFiles: 94 return inFiles.length == 0; 95 case RangeOver.database: 96 return db.length == 0; 97 } 98 } 99 100 size_t length() @safe pure nothrow const @nogc { 101 final switch (kind) { 102 case RangeOver.inFiles: 103 return inFiles.length; 104 case RangeOver.database: 105 return db.length; 106 } 107 } 108 }