Modul:Programmieren in C/C++:Vorlage:CompilerExplorerLink
Modulbeschreibung
Diese Vorlage erzeugt die URL für einen Link zum Compiler Explorer.
Zur Vermeidung von
- doppelter Datenhaltung, d.h. Code sowohl im Buch als auch im CompilerExplorer (mittels KurzLinks) zu pflegen
- 'unnötigen' Code (wie z.B. Include-Anweisungen, Funktionsrumpf, ..) im Buch zu vermeiden und damit den Blick aufs wesentliche zu lenken.
ist hier ein LUA Modul vorhanden, bei welchen über die Übergabeparameter beim Funktionsaufruf der vollständige auszuführende Code übergeben wird. Das Modul erzeugt aus diesen Übergabeparameter eine URL zum Aufruf des CompilerExplorers. Dies ermöglicht es, sowohl den Beispielcode als auch den vollständigen Code im Buch zu pflegen. Ergänzend können über den Funktionsaufruf auch Compilerschalter, der Compiler selbst und mehrere Source-Dateien übergeben werden.
Ein typischer Aufruf dieser Vorlage sieht wie folgt aus:
{{:Programmieren in C/C++:Vorlage:CompilerExplorerLink|main_c=#include <stdio.h>
void main(){
printf("Hello World!");
} }}
Und erzeugt folgenden HTML-Code:
https://www.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:example.c,fontScale:14,fontUsePx:'0',j:1,lang:___c,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'%23include+%3Cstdio%2Eh%3E%0Avoid+main%28%29%7B%0A++++printf%28%22Hello+World!!%22%29%3B%0A%7D'),l:'5',n:'0',o:example.c,t:'0')),header:(),k:50,l:'4',m:100,n:'0',o:%27%27,s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:cgsnapshot,compilerOutShown:'0',execArgs:%27%27,execStdin:%27%27,fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:%27%27,overrides:!(),runtimeTools:!(),source:'1',stdinPanelShown:'1',wrap:'1'),l:'5',n:'0',o:'Executor',t:'0')),header:(),k:50,l:'4',m:100,n:'0',o:%27%27,s:0,t:'0')),l:'2',n:'0',o:%27%27,t:'0')),version:4
Diese URL kann man dann in einem Link einfügen: Hello World!
Folgendes gilt es zu beachten:
- Dateinamen und Inhalt jeder einzelnen verwendeten Datei bilden ein Schlüssel-Wert-Paar, wobei der Dateiname der Schüssel und der Dateiinhalt der Wert ist. Dabei ist zu beachten, dass Punkte in den Dateinamen durch Unterstriche (_) zu ersetzen sind, da es sonst zu einer Fehlermeldung kommt. Pipes (|) trennen die einzelnen Dateien voneinader. Wichtig: Bei mehr als einer Datei muss die erste Datei example.<dateiendung> heißen (wobei <dateiendung> je nach Sprache durch c, cpp oder java zu ersetzen ist) bzw. CMakeLists.txt, wenn es sich im ein CMake-Projekt handelt.
- Doppelte geschweifte Klammern ({{ und }}) sind innerhalb des Quellcodes nicht gestattet und müssen immer durch ein Leerzeichen voneinander getrennt werden ({ { bzw. } }), da sie sonst als Anfang oder Ende einer Wiki-Vorlage interpretiert werden. Deshalb muss auch nach eine schließenden geschweiften Klammer am Ende einer Datei ein Leerzeichen oder Zeilenumbruch gesetzt werden.
- Pipes (|) müssen im Quellcode durch {{!}} ersetzt werden, da sie sonst als Feldtrenner interpertiert werden.
- Es gibt folgende optionale Parameter, die ebenfalls Schlüssel-Wert-Paare bilden und ebenfalls durch Pipes voneinander getrennt werden:
- lang gibt die verwendete Programmiersprache an, wobei bisher nur C, C++ und Java sowohl groß als auch klein geschrieben möglich sind (standardmäßig C)
- compiler enthält den Namen des verwendeten Compilers bzw. JDK-Version (standardmäßig "gsnapshot" für C bzw. "cgsnapshot" für C++ bzw. "java1601"):
- Für GCC-Compiler beginnt der Name mit cg gefolgt von der Versionsnummer ohne Punkte (also steht cg132 für GCC 13.2). Eine vollständige Liste mit anderen möglichen C-Compilern kann man den Dateien c.amazon.properties und c.default.properties im GitHub Repositiory des Compiler Explorers entnehmen.
- Für G++-Compiler beginnt der Name mit g gefolgt von der Versionsnummer ohne Punkte (also steht g132 für G++ 13.2). Eine vollständige Liste mit anderen möglichen C++-Compilern kann man den Dateien c++.amazon.properties und c++.default.properties im GitHub Repositiory des Compiler Explorers entnehmen.
- Für die JDK-Version beginnt der Name mit java gefolgt von der Versionsnummer ohne Punkte (also steht java1601 für JDK 16.0.1). Eine Übersicht der implementierten JDK-Versionen kann man der Datei java.amazon.properties im GitHub Repositiory des Compiler Explorers entnehmen.
- Wenn man CMake verwendet, sind die folgenden Optionen wichtig:
- isCMakeProject gibt an, ob es sich im ein CMake-Projekt handelt (standardmäßig false)
- CMakeArgs enhält die CMake Arguments (standardmäßig "" (ein leerer String))
- CMakeCustomOutputFilename enthält den Namen der Ausgabedatei (standardmäßig "" (ein leerer String))
- libs enthält eingebundene C- und C++-Bibliotheken. Jede Bibliothek wird nach folgendem Schema eingebunden: (name:<name>,ver:'<versionsnummer'). Dabei steht <name> für den Compiler Explorer-internen Namen der Bibliothek und <versionsnummer> für deren Compiler Explorer-interne Versionsnummer. Kommata trennen die einzelnen Bibiliotheken voneinander. Eine vollständige Liste mit anderen möglichen C-Compilern kann man den Dateien c.amazon.properties (für C-Bibliotheken) und c++.amazon.properties (für C++-Bibliotheken) im GitHub Repositiory des Compiler Explorers entnehmen. (standardmäßig "" (ein leerer String))
- Über h lässt sich einstellen, ob ein Executor-Fenster (e), ein Compiler-Fenster (c), ein Compiler-Fenster mit GCC Tree/RTL Viewer (g) oder ein Compiler-Fenster mit Präprozessor-Ausgabe (p) angezeigt werden soll (standardmäßig e)
- Folgende Optionen gibt es für das Executor-Fenster:
- execArgsPanelShown gibt an, ob die Execution Arguments angezeigt werden (standardmäßig false)
- execCompilationPanelShown gibt an, ob der Compiler und die Compiler Options angezeigt werden (standardmäßig true)
- execCompilerOutputShown gibt an, ob der Compiler Output angezeigt wird (standardmäßig true)
- execArgs enthält die Execution Arguments (standardmäßig "" (ein leerer String))
- execStdin enthät den Stdin (standardmäßig "" (ein leerer String))
- execCompilerOptions wird für die Compiler-Optionen verwendet (standardmäßig "" (ein leerer String))
- execStdinPanelShown gibt an, ob das Stdin angezeigt wird (standardmäßig false)
- execLineWrap gibt an, ob es einen automatischen Zeilenumbruch gibt (standardmäßig false)
- execEnv enthält Umgebungsvariablen, die als durch Semikolons getrennte Schlüssel-Wert-Paare eingetragen werden (standardmäßig "" (ein leerer String))
- Für das Compiler-Fenster gibt es folgende Filter:
- comFilterB gibt an, ob der Filter 'unused labels' angeschaltet werden soll (standardmäßig true)
- comBinary gibt an, die Ausgabeoption 'Link to binary and disassemble the output' angeschaltet werden soll (standardmäßig false)
- comBinaryObject gibt an, ob die Ausgabeoption 'Compare to binary object and disassemble the output' angeschaltet werden soll (standardmäßig false)
- comFilterCommentOnly gibt an, ob der Filter 'comments' angeschaltet werden soll (standardmäßig true)
- comDemangle gibt an, ob die Ausgabeoption 'Demangle output' angeschaltet werden soll (standardmäßig true)
- comFilterDirectives gibt an, ob der Filter 'directives' angeschaltet werden soll (standardmäßig true)
- comExecute gibt an, ob die Ausgabeoption 'Execute the code and show its output' angeschaltet werden soll (standardmäßig false)
- comIntel gibt an, ob die Ausgabeoption 'Output disassembly in Intel syntax' angeschaltet werden soll (standardmäßig true)
- comFilterLibraryCode gibt an, ob der Filter 'library functions' angeschaltet werden soll (standardmäßig true)
- comFilterTrim gibt an, ob der Filter 'horizontal whitespace' angeschaltet werden soll (standardmäßig false)
- Obwohl es für GCC Tree/RTL Viewer verschiedene Optionen und Einstellungen gibt, sind hier alle Optionen deaktiviert, alle Filter aktiviert und es wurde original (tree) als pass ausgewählt. Diese Einstellungen lassen durch dieses Script nicht ändern.
- Für die Präprozessor-Ausgabe gibt es folgende Optionen:
- preClangFormat gibt an, ob die Ausgabe im Clang-Format erfolgen soll (standardmäßig false)
- preFilterHeaders gibt an, ob die Header herausgefiltert (d.h. nicht angezeigt) werden sollen (standardmäßig true)
- Folgende Optionen gibt es für das Executor-Fenster:
- Diese Dokumentation wurde mithilfe von Modul:LuaDokumentation erstellt und befindet sich im Quelltext.
- Liste der Unterseiten
--- Diese Vorlage erzeugt die URL für einen Link zum [https://www.godbolt.org/ Compiler Explorer].
--
-- Zur Vermeidung von
-- * doppelter Datenhaltung, d.h. Code sowohl im Buch als auch im CompilerExplorer (mittels KurzLinks) zu pflegen
-- * 'unnötigen' Code (wie z.B. Include-Anweisungen, Funktionsrumpf, ..) im Buch zu vermeiden und damit den Blick aufs wesentliche zu lenken.
-- ist hier ein LUA Modul vorhanden, bei welchen über die Übergabeparameter beim Funktionsaufruf der vollständige auszuführende Code übergeben wird. Das Modul erzeugt aus diesen Übergabeparameter eine URL zum Aufruf des CompilerExplorers. Dies ermöglicht es, sowohl den Beispielcode als auch den vollständigen Code im Buch zu pflegen. Ergänzend können über den Funktionsaufruf auch Compilerschalter, der Compiler selbst und mehrere Source-Dateien übergeben werden.
--
-- Ein typischer Aufruf dieser Vorlage sieht wie folgt aus:<br>
-- '''<nowiki>{{:Programmieren in C/C++:Vorlage:CompilerExplorerLink|main_c=#include <stdio.h></nowiki>'''<br>
-- '''<nowiki>void main(){</nowiki>'''<br>
-- '''<nowiki> printf("Hello World!");</nowiki>'''<br>
-- '''<nowiki>} }}</nowiki>'''<br>
-- Und erzeugt folgenden HTML-Code:<br>
-- '''{{:Programmieren in C/C++:Vorlage:CompilerExplorerLink|main_c=#include <stdio.h>
-- void main(){
-- printf("Hello World!");
-- } }}'''<br>
-- Diese URL kann man dann in einem Link einfügen: '''[{{:Programmieren in C/C++:Vorlage:CompilerExplorerLink|main_c=#include <stdio.h>
-- void main(){
-- printf("Hello World!");
-- } }} Hello World!]'''
--
-- Folgendes gilt es zu beachten:
-- * Dateinamen und Inhalt jeder einzelnen verwendeten Datei bilden ein Schlüssel-Wert-Paar, wobei der Dateiname der Schüssel und der Dateiinhalt der Wert ist. Dabei ist zu beachten, dass Punkte in den Dateinamen durch Unterstriche ('''_''') zu ersetzen sind, da es sonst zu einer Fehlermeldung kommt. Pipes ('''|''') trennen die einzelnen Dateien voneinader. '''Wichtig''': Bei mehr als einer Datei muss die erste Datei ''example.<dateiendung>'' heißen (wobei <dateiendung> je nach Sprache durch ''c'', ''cpp'' oder ''java'' zu ersetzen ist) bzw. ''CMakeLists.txt'', wenn es sich im ein CMake-Projekt handelt.
-- * Doppelte geschweifte Klammern ('''<nowiki>{{</nowiki>''' und '''<nowiki>}}</nowiki>''') sind innerhalb des Quellcodes nicht gestattet und müssen immer durch ein Leerzeichen voneinander getrennt werden ('''{ {''' bzw. '''} }'''), da sie sonst als Anfang oder Ende einer Wiki-Vorlage interpretiert werden. Deshalb muss auch nach eine schließenden geschweiften Klammer am Ende einer Datei ein Leerzeichen oder Zeilenumbruch gesetzt werden.
-- * Pipes ('''|''') müssen im Quellcode durch '''<nowiki>{{!}}</nowiki>''' ersetzt werden, da sie sonst als Feldtrenner interpertiert werden.
-- * Es gibt folgende optionale Parameter, die ebenfalls Schlüssel-Wert-Paare bilden und ebenfalls durch Pipes voneinander getrennt werden:
-- ** ''lang'' gibt die verwendete Programmiersprache an, wobei bisher nur ''C'', ''C++'' und ''Java'' sowohl groß als auch klein geschrieben möglich sind (standardmäßig '''C''')
-- ** ''compiler'' enthält den Namen des verwendeten Compilers bzw. JDK-Version (standardmäßig '''"gsnapshot"''' für C bzw. '''"cgsnapshot"''' für C++ bzw. '''"java1601"'''):
-- *** Für GCC-Compiler beginnt der Name mit cg gefolgt von der Versionsnummer ohne Punkte (also steht cg132 für GCC 13.2). Eine vollständige Liste mit anderen möglichen C-Compilern kann man den Dateien [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c.amazon.properties c.amazon.properties] und [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c.defaults.properties c.default.properties] im [https://github.com/compiler-explorer GitHub Repositiory] des [https://www.godbolt.org Compiler Explorers] entnehmen.
-- *** Für G++-Compiler beginnt der Name mit g gefolgt von der Versionsnummer ohne Punkte (also steht g132 für G++ 13.2). Eine vollständige Liste mit anderen möglichen C++-Compilern kann man den Dateien [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c++.amazon.properties c++.amazon.properties] und [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c++.defaults.properties c++.default.properties] im [https://github.com/compiler-explorer GitHub Repositiory] des [https://www.godbolt.org Compiler Explorers] entnehmen.
-- *** Für die JDK-Version beginnt der Name mit java gefolgt von der Versionsnummer ohne Punkte (also steht java1601 für JDK 16.0.1). Eine Übersicht der implementierten JDK-Versionen kann man der Datei [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/java.amazon.properties java.amazon.properties] im [https://github.com/compiler-explorer GitHub Repositiory] des [https://www.godbolt.org Compiler Explorers] entnehmen.
-- ** Wenn man CMake verwendet, sind die folgenden Optionen wichtig:
-- *** ''isCMakeProject'' gibt an, ob es sich im ein CMake-Projekt handelt (standardmäßig '''false''')
-- *** ''CMakeArgs'' enhält die CMake Arguments (standardmäßig '''""''' (ein leerer String))
-- *** ''CMakeCustomOutputFilename'' enthält den Namen der Ausgabedatei (standardmäßig '''""''' (ein leerer String))
-- ** ''libs'' enthält eingebundene C- und C++-Bibliotheken. Jede Bibliothek wird nach folgendem Schema eingebunden: ''(name:<name>,ver:'<versionsnummer')''. Dabei steht <name> für den Compiler Explorer-internen Namen der Bibliothek und <versionsnummer> für deren Compiler Explorer-interne Versionsnummer. Kommata trennen die einzelnen Bibiliotheken voneinander. Eine vollständige Liste mit anderen möglichen C-Compilern kann man den Dateien [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c.amazon.properties c.amazon.properties] (für C-Bibliotheken) und [https://github.com/compiler-explorer/compiler-explorer/blob/e861f94a0d32622395536175c5f3df5880bc8744/etc/config/c++.amazon.properties c++.amazon.properties] (für C++-Bibliotheken) im [https://github.com/compiler-explorer GitHub Repositiory] des [https://www.godbolt.org Compiler Explorers] entnehmen. (standardmäßig '''""''' (ein leerer String))
-- ** Über ''h'' lässt sich einstellen, ob ein Executor-Fenster (''e''), ein Compiler-Fenster (''c''), ein Compiler-Fenster mit GCC Tree/RTL Viewer (''g'') oder ein Compiler-Fenster mit Präprozessor-Ausgabe (''p'') angezeigt werden soll (standardmäßig '''e''')
-- *** Folgende Optionen gibt es für das Executor-Fenster:
-- **** ''execArgsPanelShown'' gibt an, ob die Execution Arguments angezeigt werden (standardmäßig '''false''')
-- **** ''execCompilationPanelShown'' gibt an, ob der Compiler und die Compiler Options angezeigt werden (standardmäßig '''true''')
-- **** ''execCompilerOutputShown'' gibt an, ob der Compiler Output angezeigt wird (standardmäßig '''true''')
-- **** ''execArgs'' enthält die Execution Arguments (standardmäßig '''""''' (ein leerer String))
-- **** ''execStdin'' enthät den Stdin (standardmäßig '''""''' (ein leerer String))
-- **** ''execCompilerOptions'' wird für die Compiler-Optionen verwendet (standardmäßig '''""''' (ein leerer String))
-- **** ''execStdinPanelShown'' gibt an, ob das Stdin angezeigt wird (standardmäßig '''false''')
-- **** ''execLineWrap'' gibt an, ob es einen automatischen Zeilenumbruch gibt (standardmäßig '''false''')
-- **** ''execEnv'' enthält Umgebungsvariablen, die als durch Semikolons getrennte Schlüssel-Wert-Paare eingetragen werden (standardmäßig '''""''' (ein leerer String))
-- *** Für das Compiler-Fenster gibt es folgende Filter:
-- **** ''comFilterB'' gibt an, ob der Filter 'unused labels' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comBinary'' gibt an, die Ausgabeoption 'Link to binary and disassemble the output' angeschaltet werden soll (standardmäßig '''false''')
-- **** ''comBinaryObject'' gibt an, ob die Ausgabeoption 'Compare to binary object and disassemble the output' angeschaltet werden soll (standardmäßig '''false''')
-- **** ''comFilterCommentOnly'' gibt an, ob der Filter 'comments' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comDemangle'' gibt an, ob die Ausgabeoption 'Demangle output' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comFilterDirectives'' gibt an, ob der Filter 'directives' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comExecute'' gibt an, ob die Ausgabeoption 'Execute the code and show its output' angeschaltet werden soll (standardmäßig '''false''')
-- **** ''comIntel'' gibt an, ob die Ausgabeoption 'Output disassembly in Intel syntax' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comFilterLibraryCode'' gibt an, ob der Filter 'library functions' angeschaltet werden soll (standardmäßig '''true''')
-- **** ''comFilterTrim'' gibt an, ob der Filter 'horizontal whitespace' angeschaltet werden soll (standardmäßig '''false''')
-- *** Obwohl es für GCC Tree/RTL Viewer verschiedene Optionen und Einstellungen gibt, sind hier alle Optionen deaktiviert, alle Filter aktiviert und es wurde ''original (tree)'' als ''pass'' ausgewählt. Diese Einstellungen lassen durch dieses Script nicht ändern.
-- *** Für die Präprozessor-Ausgabe gibt es folgende Optionen:
-- **** ''preClangFormat'' gibt an, ob die Ausgabe im Clang-Format erfolgen soll (standardmäßig '''false''')
-- **** ''preFilterHeaders'' gibt an, ob die Header herausgefiltert (d.h. nicht angezeigt) werden sollen (standardmäßig '''true''')
local CompilerExplorerLink = {}
-- Konvertiert Dezimal-Integer in Hexadezimal-Integer
local function hex(dec)
local hb = math.floor(dec/16)
local lb = dec%16
if lb > 9 then
lb = string.char(lb +55)
end
if hb > 9 then
hb = string.char(hb +55)
end
return hb .. lb
end
-- Wandelt einen String so um, dass er innerhalb einer URL verwendet werden kann
-- Dabei werden Leerzeichen durch + ersetzt, andere Sonderzeichen durch ihren Hex-Code und
-- einfachen Anführungszeichen(') und Ausrufezeichen(!) ein Ausrufungszeichen vorgestellt
local function transform(code)
local codestring = ""
if code == nil then
return "";
end
for i = 1, #code, 1 do
local zeichen = code:byte(i)
if (((zeichen >= 48) and (zeichen <=57)) or ((zeichen >= 65) and (zeichen <=90)) or ((zeichen >= 97) and (zeichen <=122))) then
codestring = codestring .. string.char(zeichen)
elseif zeichen == 39 then
codestring = codestring .. "!'"
elseif zeichen == 33 then
codestring = codestring .. "!!"
elseif zeichen == 95 then
codestring = codestring .. "_"
elseif zeichen == 32 then
codestring = codestring .. "+"
else
codestring = codestring .. "%" .. hex(zeichen)
end
end
return codestring
end
-- Wandelt eine 1 in eine 0 um und umgekehrt
-- Dies ist notwendig, da der Compiler Optionen eine 0 in der URL als true und eine 1 als false interpretiert
local function invert(a)
if a == "true" then
return "0"
elseif a == "false" then
return "1"
else
return nil
end
end
-- Dies Funktion
local function divEnv(source)
local div = string.find(source,"=")
local name = string.sub(source,1,div-1)
local value = string.sub(source,div+1)
if #name == 1 then
name = "___" .. name
end
if #value == 1 then
value = "___" .. value
else
value = "'" .. value .. "'"
end
return "(name:" .. name .. ",value:" .. value .. ")"
end
-- Diese Funktion konvertiert den String mit den Umgebungsvariablen in das vom Compiler Explorer verlangte Format
local function convEnv(source)
local overrides = ""
local ende = 1
while ende ~= nil do
ende = string.find(source,";")
if ende ~= nil then
overrides = overrides .. divEnv(string.sub(source,1, ende-1)) ..","
source = string.sub(source,ende+1)
end
end
return overrides .. divEnv(source)
end
-- Erzeugt eine URL zum Compiler Explorer
-- für jede "Datei" wird ein Eintrag in den Arrays "code" (der Inhalt der Datei)
-- und "filename" (der Name der Datei) benötigt.
-- Optionen können weggelassen werden. in diesem fall werden Standardwerte benutzt.
local function convert(source)
-- Die Standardwerte der Optionen werden festgelegt
local options = ""
local compiler = "cgsnapshot"
local execArgsPanelShown = "1"
local execStdin = ""
local execArgs = ""
local stdinPanelShown = "1"
local wrap = "1"
local compilerOutShown = "0"
local compilationPanelShown = "0"
local isCMakeProject = "1"
local cmakeArgs = ""
local customOutputFilename = ""
local libs = ""
local lang = "___c"
local h = "e"
local b = "0"
local binary = "1"
local binaryObject = "1"
local commentOnly = "0"
local demangle = "0"
local directives = "0"
local execute = "1"
local intel = "0"
local libraryCode = "0"
local trim = "1"
local runtimeTools = ""
local clangformat = "1"
local filterheaders = "0"
-- falls vorhanden, werden die Optionen und Bibliotheken ausgewertet
if source.lang ~= nil then
lang = string.lower(source.lang)
if lang == "c++" then
compiler = "gsnapshot"
elseif lang == "java" then
compiler = "java1601"
elseif lang == "c" then
lang = "___c"
end
end
if (source.execArgsPanelShown == "true") or (source.execArgsPanelShown == "false") then
execArgsPanelShown = invert(source.execArgsPanelShown)
end
if (source.execCompilationPanelShown == "true") or (source.execCompilationPanelShown == "false") then
compilationPanelShown = invert(source.execCompilationPanelShown)
end
if source.compiler ~= nil then
compiler = compiler
end
if (source.execCompilerOutputShown == "true") or (source.execCompilerOutputShown == "false") then
compilerOutShown = invert(source.execCompilerOutputShown)
end
if source.execArgs ~= nil then
execArgs = source.execArgs
end
if source.execStdin ~= nil then
execStdin = source.execStdin
end
if source.execCompilerOptions ~= nil then
options = source.execCompilerOptions
end
if (source.execStdinPanelShown == "true") or (source.execStdinPanelShown == "false") then
stdinPanelShown = invert(source.execStdinPanelShown)
end
if (source.execLineWrap == "true") or (source.execLineWrap == "false") then
wrap = invert(source.execLineWrap)
end
if (source.isCMakeProject == "true") or (source.isCMakeProject == "false") then
isCMakeProject = invert(source.isCMakeProject)
end
if source.CMakeArgs ~= nil then
cmakeArgs = source.CMakeArgs
end
if source.CMakeCustomOutputFilename ~= nil then
customOutputFilename = source.CMakeCustomOutputFilename
end
if source.libs ~= nil then
libs = source.libs
end
if source.h ~= nil then
h = source.h
end
if (source.comFilterB == "true") or (source.comFilterB == "false") then
b = invert(source.b)
end
if ((source.comBinary == "true") and (source.comBinaryObject == "false")) or (source.comBinary == "false") then
binary = invert(source.binary)
end
if ((source.comBinary == "false") and (source.comBinaryObject == "true")) or (source.comBinaryObject == "false") then
binaryObject = invert(source.binaryObject)
end
if (source.comFilterCommentOnly == "true") or (source.comFilterCommentOnly == "false") then
commentOnly = invert(source.commentOnly)
end
if (source.comDemangle == "true") or (source.comDemangle == "false") then
demangle = invert(source.demangle)
end
if (source.comFilterDirectives == "true") or (source.comFilterDirectives == "false") then
directives = invert(source.directives)
end
if (source.comExecute == "true") or (source.comExecute == "false") then
execute = invert(source.execute)
end
if (source.comIntel == "true") or (source.comIntel == "false") then
intel = invert(source.intel)
end
if (source.comFilterLibraryCode == "true") or (source.comFilterLibraryCode == "false") then
libraryCode = invert(source.libraryCode)
end
if (source.comFilterTrim == "true") or (source.comFilterTrim == "false") then
trim = invert(source.trim)
end
if (source.preClangFormat == "true") or (source.preClangFormat == "false") then
clangformat = invert(source.preClangFormat)
end
if (source.preFilterHeaders == "true") or (source.preFilterHeaders == "false") then
filterheaders = invert(source.preFilterHeaders)
end
if source.execEnv ~= nil then
runtimeTools = "(name:env,options:!(" .. convEnv(source.execEnv) .. "))"
end
local name = {}
local code = {}
for key,value in pairs(source) do
if key:find('_') ~= nil then
key = string.gsub(key,'_','.')
name[#name+1] = key
code[#code+1] = value
end
end
local breite = 100
local hoehe = 100
if #name > 1 then
hoehe = 50
end
if (h == g) or (h == p) then
breite = 100/(#name+2)
else
breite = 100/(#name+1)
end
-- falls kein Dateiname oder Quellcode angegeben wurde,
-- wird nur eine aus Schema und Host gebildete URL zurückgegeben
if (#name == 0) and (#code ==0) then
return "https://www.godbolt.org/"
end
-- Der Fragment-Teil der URL wird erzeugt
local url = "g:!((g:!("
-- da der Compiler Explorer verlangt, dass die Hauptdatei einen bestimmten Namen hat, wird dies hier sicher gestellt
if #name == 1 then
if lang == "c++" then
name[1] = "example.cpp"
elseif lang == "java" then
name[1] = "example.java"
else
name[1] = "example.c"
end
isCMakeProject = "1"
end
for i = 1, #name, 1 do
url = url .. "(g:!((h:codeEditor,i:(filename:" .. name[i] .. ",fontScale:14,fontUsePx:'0',j:" .. i .. ",lang:" .. transform(lang) .. ",selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'" .. transform(code[i]) .. "'),l:'5',n:'0',o:" .. name[i] .. ",t:'0')),header:(),k:" .. breite .. ",l:'4',m:100,n:'0',o:%27%27,s:0,t:'0'),"
end
url = url .. "(g:!(("
if #name > 1 then
url = url .. "g:!((h:tree,i:(cmakeArgs:%27" .. cmakeArgs .. "%27,compilerLanguageId:" .. transform(lang) .. ",customOutputFilename:%27" .. customOutputFilename .. "%27,files:!("
for i = 1, #name, 1 do
url = url .. "(editorId:" .. i .. ",fileId:" .. i .. ",filename:" .. name[i] .. ",g:%27%27,isIncluded:'0',isMainSource:'"
if isCMakeProject == "0" then
if name[i] == "CMakeLists.txt" then
url = url .. "0"
else
url = url .."1"
end
else
if name[i] == "example.c" then
url = url .. "0"
else
url = url .."1"
end
end
url = url .. "',isOpen:'0',langId:%27%27)"
if i < #name then
url = url .. ","
end
end
url = url .. "),isCMakeProject:'".. isCMakeProject .. "',j:1,newFileId:" .. (#name+1) .. "),l:'5',n:'0',o:'Tree',t:'0')),header:(),l:'4',m:" .. hoehe .. ",n:'0',o:%27%27,s:0,t:'0'),(g:!(("
end
if h == "e" then
url = url .. "h:executor,i:(argsPanelShown:'" .. execArgsPanelShown .. "',compilationPanelShown:'" .. compilationPanelShown .. "',compiler:" .. compiler .. ",compilerOutShown:'" .. compilerOutShown .. "',execArgs:"
if execArgs == "___" then
url = url .. execArgs
else
url = url .. "%27" .. transform(execArgs) .. "%27"
end
url = url .. ",execStdin:%27" .. transform(execStdin) .."%27,fontScale:14,fontUsePx:'0',j:1,lang:" .. transform(lang) .. ",libs:!(" .. libs .. "),options:%27" .. transform(options) .. "%27,overrides:!(),runtimeTools:!(" .. runtimeTools .. "),source:'1',stdinPanelShown:'" .. stdinPanelShown .. "',"
if #name > 1 then
url = url .. "tree:1,"
end
url = url .. "wrap:'" .. wrap .. "'),l:'5',n:'0',o:'Executor',t:'0'"
else
url = url .. "h:compiler,i:(compiler:" .. compiler .. ",filters:(b:'" .. b .. "',binary:'" .. binary .. "',binaryObject:'" .. binaryObject .. "',commentOnly:'" .. commentOnly .. "',debugCalls:'1',demangle:'" .. demangle .. "',directives:'" .. directives .. "',execute:'" .. execute .. "',intel:'" .. intel .. "',libraryCode:'" .. libraryCode .. "',trim:'" .. trim .. "'),"
url = url .. "flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:" .. lang .. ",libs:!(" .. libs .. "),options:%27" .. transform(options) .. "%27,overrides:!(),"
url = url .. "selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),"
if #name > 1 then
url = url .. "tree:1,"
end
url = url .. "source:'1'),l:'5',n:'0',o:'compiler',t:'0'"
end
url = url ..")),header:(),k:" .. breite .. ",l:'4',m:" .. hoehe .. ",n:'0',o:%27%27,s:0,t:'0')"
if #name > 1 then
url = url .. "),k:" .. breite .. ",l:'3',n:'0',o:%27%27,s:0,t:'0')"
end
if h == "g" then
url = url ..",(g:!((h:gccdump,i:(addressOption:'1',allOption:'1',blocksOption:'1',command_prefix:(),compilerName:%27%27,detailsOption:'1',editorid:1,filename_suffix:t.original,fontScale:14,fontUsePx:'0',gimpleFeOption:'1',ipaDump:'0',j:1,linenoOption:'1',name:(),rawOption:'1',rtlDump:'0',selectedPass:t.original,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),slimOption:'1',statsOption:'1',treeDump:'0',treeid:0,uidOption:'1',vopsOption:'1'),l:'5',n:'0',o:'GCC+Tree/RTL+Viewer',t:'0')),k:" .. breite .. ",l:'4',n:'0',o:%27%27,s:0,t:'0')),"
elseif h == "p" then
url = url ..",(g:!((h:pp,i:(clang-format:'" .. clangformat .. "',editorid:1,filter-headers:'" .. filterheaders .. "',fontScale:14,fontUsePx:'0',j:1,treeid:0),l:'5',n:'0',o:'Preprocessor+Output',t:'0')),k:" .. breite .. ",l:'4',n:'0',o:%27%27,s:0,t:'0')),"
else
url = url .. "),"
end
url = url .. "l:'2',n:'0',o:%27%27,t:'0')),version:4"
-- Die vollständieg URL (Schema + Host + Fragment) wird zurückgegeben
return "https://www.godbolt.org/#" .. url
end
-- Hauptprogramm: Erzeugt einen Link zum Compiler Explorer
function CompilerExplorerLink.createLink(frame)
local source = frame:getParent().args
return tostring(convert(source))
end
return CompilerExplorerLink