1 module support; // dockerfile_parser; 2 3 struct Result(T) 4 { 5 string errorMessage; 6 T* result; 7 } 8 9 struct Command 10 { 11 string command; 12 string subCommand; 13 bool json; 14 string original; 15 int startLine; 16 int endLine; 17 string[] flags; 18 string[] values; 19 } 20 21 export extern(C) 22 void* return_success(void* ret) 23 { 24 auto result = new Result!(void*)(null,cast(void**)ret); 25 return cast(void*) result; 26 } 27 28 export extern(C) 29 void* raise(const(char)* errorMessage) 30 { 31 import std..string : toStringz, fromStringz; 32 import core.stdc.stdlib : free; 33 bool shouldFree = true; 34 auto niceErrorMessage = (errorMessage is null) ? "UNKNOWN GOLANG ERROR" : errorMessage.fromStringz.idup; 35 auto result = new Result!(void*)(niceErrorMessage); 36 if (errorMessage !is null) 37 free(cast(void*)errorMessage); 38 return cast(void*) result; 39 } 40 41 export extern(C) 42 void* command(char* cmd, char* sub_cmd, int json, char* original, int start_line, int end_line, void* flags, void* value) 43 { 44 import std..string : fromStringz; 45 import core.stdc.stdlib : free; 46 47 auto ret = new Command; 48 ret.command = cmd.fromStringz.idup; 49 ret.subCommand = sub_cmd.fromStringz.idup; 50 ret.json = (json != 0); 51 ret.original = original.fromStringz.idup; 52 ret.startLine = start_line; 53 ret.endLine = end_line; 54 auto flagsV = cast(StringSlice*) flags; 55 ret.flags = (*flagsV).values; 56 auto valuesV = cast(StringSlice*) value; 57 ret.values = (*valuesV).values; 58 free(cmd); 59 free(sub_cmd); 60 free(original); 61 return cast(void*) new Result!Command(null,ret); 62 } 63 64 extern(C) void* parse_string(const(char)* s); 65 extern(C) void* parse_file(const(char)* filename); 66 extern(C) void* all_commands(); 67 68 alias CommandResult = Result!Command; 69 alias CommandSlice = Slice!Command; 70 alias CommandSliceResult = Result!(Slice!Command); 71 alias StringSlice = Slice!string; 72 alias StringSliceResult = Result!(Slice!string); 73 74 Command[] parseString(string s) 75 { 76 import std..string : toStringz, fromStringz; 77 import std.exception : enforce; 78 auto p = cast(CommandSliceResult*) parse_string(s.toStringz); 79 enforce(p !is null, "parse_string failed"); 80 enforce(p.errorMessage.length ==0, p.errorMessage); 81 auto result = *p.result; 82 return result.values; 83 } 84 85 Command[] parseFile(string filename) 86 { 87 import std..string : toStringz, fromStringz; 88 import std.exception : enforce; 89 auto p = cast(CommandSliceResult*) parse_file(filename.toStringz); 90 enforce(p !is null, "parse_file failed"); 91 enforce(p.errorMessage.length ==0, p.errorMessage); 92 auto result = *p.result; 93 return result.values; 94 } 95 96 string[] allCommands() 97 { 98 import std..string : fromStringz; 99 import std.exception : enforce; 100 auto p = cast(StringSliceResult*) all_commands(); 101 enforce(p !is null, "all_commands failed"); 102 enforce(p.errorMessage.length ==0, p.errorMessage); 103 auto result = *p.result; 104 return result.values; 105 } 106 107 108 struct Slice(T) 109 { 110 T[] values; 111 } 112 113 export extern(C) 114 void* stringSlice(size_t length) 115 { 116 auto ret = new Slice!string; 117 ret.values.length = length; 118 return cast(void*) ret; 119 } 120 121 export extern(C) 122 void* commandSlice(size_t length) 123 { 124 auto ret = new Slice!Command; 125 ret.values.length = length; 126 return cast(void*) ret; 127 } 128 129 export extern(C) 130 void setStringElement(void* sliceV, size_t i, char* s) 131 { 132 import core.stdc.stdlib : free; 133 import std.exception : enforce; 134 import std..string : fromStringz; 135 136 auto slice = cast(StringSlice*) sliceV; 137 enforce(slice.values.length > i); 138 slice.values[i] = fromStringz(s).idup; 139 free(s); 140 } 141 142 export extern(C) 143 void setCommandElement(void* sliceV, size_t i, void* p) 144 { 145 import std.exception : enforce; 146 assert(p !is null, "setCommandElement called with null"); 147 auto slice = cast(CommandSlice*) sliceV; 148 enforce(slice.values.length > i); 149 auto pTyped = cast(CommandResult*) p; 150 slice.values[i] = *pTyped.result; 151 } 152