Modul:Vorlage:CompilerExplorerLink
Diese Vorlage erzeugt die URL für einen Link zum Compiler Explorer.
- 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 Hauptdatei example.c heißen 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.
- Für den Executor Frame gibt es folgende optionale Parameter, die ebenfalls Schlüssel-Wert-Paare bilden, die ebenfalls durch Pipes voneinander getrennt werden:
- 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)
- execCompiler enthält den Namen des verwendeten Compilers (standardmäßig "cg122"):
- Für GCC-Compiler beginnt der Name mit cg gefolgt von der Versionsnummer ohne Punkte (also steht cg122 für GCC 12.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.
- execCompilerOutputShown gibt an, ob der Compiler Output angezeigt wird (standardmäßig true)
- execArgs enthält die Execution Arguments (standardmäßig ___)
- 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)
- Wenn man CMake verwendet, sind die folgenden Optionen wichtig, die auch wieder Schlüssel-Wert-Paare bilden, die durch Pipes voneinander getrennt werden:
- 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))
- Folgende Bibliotheken sind dem Compiler Explorer bekannt und können ebenfalls verwendet werden, in dem man aus Schlüssel-Werte-Paare aus den Namen und der Versionsnummer (mögliche Versionen in Klammern angegeben) bildet: cs50 (910), hedley (v12), libuv (1370,1381), lua (535,540), nsimd(22-x86_64,22-arm,22-arm64,310-x86_64,310-arm,310-arm64), openssl (111c,111g), python (359,3610,376,381), simde (trunk), curl(7831), sqlite (3400).
Ein typischer Aufruf dieser Vorlage sieht wie folgt aus:
{{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:!((g:!((h:tree,i:(cmakeArgs:%27%27,compilerLanguageId:___c,customOutputFilename:%27%27,files:!((editorId:1,fileId:1,filename:example.c,g:%27%27,isIncluded:'0',isMainSource:'0',isOpen:'0',langId:%27%27)),isCMakeProject:'1',j:1,newFileId:2),l:'5',n:'0',o:'Tree+%231',t:'0')),header:(),l:'4',m:50,n:'0',o:%27%27,s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:cg122,compilerOutShown:'0',execArgs:___,execStdin:%27%27,fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:%27%27,source:'1',stdinPanelShown:'1',tree:1,wrap:'1'),l:'5',n:'0',o:'Executor+(C,+Tree+%231)',t:'0')),header:(),k:50,l:'4',m:50,n:'0',o:%27%27,s:0,t:'0')),k:50,l:'3',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!
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
-- 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 = "cg122"
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 = {}
-- falls vorhanden, werden die Optionen und Bibliotheken ausgewertet
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.execCompiler ~= nil then
compiler = source.execCompiler
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.cs50 ~= nil then
libs[#libs+1] = "(name:cs50,ver:'".. source.cs50 .. "')"
end
if source.hedley ~= nil then
libs[#libs+1] = "(name:hedley,ver:".. source.hedley .. ")"
end
if source.libuv ~= nil then
libs[#libs+1] = "(name:libuv,ver:'".. source.libuv .. "')"
end
if source.lua ~= nil then
libs[#libs+1] = "(name:lua,ver:'".. source.lua .. "')"
end
if source.nsimd ~= nil then
libs[#libs+1] = "(name:nsimd,ver:'".. source.nsimd .. "')"
end
if source.openssl ~= nil then
libs[#libs+1] = "(name:openssl,ver:'".. source.openssl .. "')"
end
if source.python ~= nil then
libs[#libs+1] = "(name:python,ver:'".. source.python .. "')"
end
if source.simde ~= nil then
libs[#libs+1] = "(name:simde,ver:".. source.simde .. ")"
end
if source.curl ~= nil then
libs[#libs+1] = "(name:curl,ver:'".. source.curl .. "')"
end
if source.sqlite ~= nil then
libs[#libs+1] = "(name:sqlite,ver:'".. source.sqlite .. "')"
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
-- falls kein Dateiname oder Quellcode angegeben wurde,
-- wird nur eine aus Schema und Host gebildete URL zurückgegeben
if (#name == 0) or (#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
name[1] = "example.c"
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:___c,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:" .. (100/(#name+1)) .. ",l:'4',m:100,n:'0',o:%27%27,s:0,t:'0'),"
end
url = url .. "(g:!((g:!((h:tree,i:(cmakeArgs:%27" .. cmakeArgs .. "%27,compilerLanguageId:___c,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+%231',t:'0')),header:(),l:'4',m:50,n:'0',o:%27%27,s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'" .. execArgsPanelShown .. "',compilationPanelShown:'" .. compilationPanelShown .. "',compiler:" .. compiler .. ",compilerOutShown:'" .. compilerOutShown .. "',execArgs:"
if execArgs == "___" then
url = url .. execArgs
else
url = url .. "'" .. transform(execArgs) .. "'"
end
url = url .. ",execStdin:%27" .. transform(execStdin) .."%27,fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!("
if #libs > 0 then
for i = 1, #libs, 1 do
url = url .. libs[i]
if i < #libs then
url = url ..","
end
end
end
url = url .. "),options:%27" .. transform(options) .. "%27,source:'1',stdinPanelShown:'" .. stdinPanelShown .. "',tree:1,wrap:'" .. wrap .. "'),l:'5',n:'0',o:'Executor+(C,+Tree+%231)',t:'0')),header:(),k:50,l:'4',m:50,n:'0',o:%27%27,s:0,t:'0')),k:" .. (100/(#name+1)) .. ",l:'3',n:'0',o:%27%27,s:0,t:'0')),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
-- Dateinamen und Quellcodes bilden ein Schlüssel-Wert-Paar,
-- wobei Punkte im Dateinamen durch '_' dargestellt werden müssen (so muss z.B. statt "main.c" "main_c" geschrieben werden)
-- Für den Executor Frame gibt es folgende Optionen, die ebenfalls Schlüssel-Wert-Paare bilden, aber angegeben werden müssen:
-- execCompilerOptions wird für die Compiler-Optionen verwendet (standardmäßig "")
-- execArgs enthält die Execution Arguments (standardmäßig ___)
-- execStdin enthät den Stdin (standardmäßig "")
-- execCompiler enthält den Namen des verwendeten Compilers (standardmäßig "cg122")
-- execArgsPanelShown gibt an, ob die Execution Arguments angezeigt werden (standardmäßig "0")
-- execStdinPanelShown gibt an, ob das Stdin angezeigt wird (standardmäßig "0")
-- execLineWrap gibt an, ob es einen automatischen Zeilenumbruch gibt (standardmäßig "0")
-- execCompilerOutputShown gibt an, ob der Compiler Output angezeigt wird (standardmäßig "1")
-- execCompilationPanelShown gibt an, ob der Compiler und die Compiler Options angezeigt werden (standardmäßig "1")
function CompilerExplorerLink.createLink(frame)
local source = frame:getParent().args
return tostring(convert(source))
end
return CompilerExplorerLink
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.