Modul:Vorlage:CompilerExplorerLink
Erscheinungsbild
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:
Lua-Fehler in Zeile 75: attempt to get length of local 'filename' (a nil value)
Diese URL kann man dann in einem Link einfügen: [Lua-Fehler in Zeile 75: attempt to get length of local 'filename' (a nil value) 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 und andere Sonderzeichen durch ihren Hex-Code
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 == 32 then
codestring = codestring .. "+"
else
codestring = codestring .. "%" .. hex(zeichen)
end
end
return codestring
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(code, filename, options)
local coptions = ""
local compiler = "cg122"
local execargs = "1"
local execstdin = "1"
local wrap = "1"
local compout = "0"
local cpanel = "0"
if options ~= nil then
if options.coptions ~= nil then
coptions = options.coptions
end
if options.compiler ~= nil then
compiler = options.compiler
end
if (options.execargs == "1") or (options.execargs == "0") then
execargs = options.execargs
end
if (options.execstdin == "1") or (options.execstdin == "0") then
execstdin = options.execstdin
end
if (options.wrap == "1") or (options.wrap == "0") then
wrap = options.wrap
end
if (options.compout == "1") or (options.compout == "0") then
compout = options.compout
end
if (options.cpanel == "1") or (options.cpanel == "0") then
cpanel = options.cpanel
end
end
local url = "https://www.godbolt.org/#g:!((g:!("
for i = 1, #filename, 1 do
if filename[i] == "main.c" then
filename[i] = "example.c"
end
url = url .. "(g:!((h:codeEditor,i:(filename:" .. filename[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:" .. filename[i] .. ",t:'0')),header:(),k:" .. (100/(#filename+1)) .. ",l:'4',m:100,n:'0',o:'',s:0,t:'0'),"
end
url = url .. "(g:!((g:!((h:tree,i:(cmakeArgs:'',compilerLanguageId:___c,customOutputFilename:'',files:!(";
for i = 1, #filename, 1 do
url = url .. "(editorId:" .. i .. ",fileId:" .. i .. ",filename:" .. filename[i] .. ",g:'',isIncluded:'0',isMainSource:'"
if filename[i] == "example.c" then
url = url .. "0"
else
url = url .."1"
end
url = url .. "',isOpen:'0',langId:'')"
if i < #filename then
url = url .. ","
end
end
url = url .. "),isCMakeProject:'1',j:1,newFileId:" .. (#filename+1) .. "),l:'5',n:'0',o:'Tree+%231',t:'0')),header:(),l:'4',m:50,n:'0',o:'',s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'" .. execargs .. "',compilationPanelShown:'" .. cpanel .. "',compiler:" .. compiler .. ",compilerOutShown:'" .. compout .. "',execArgs:___,execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:'" .. transform(coptions) .. "',source:'1',stdinPanelShown:'" .. execstdin .. "',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:'',s:0,t:'0')),k:" .. (100/(#filename+1)) .. ",l:'3',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4";
return url
end
-- Hauptprogramm: Erzeugt einen Link zum Compiler Explorer
-- die Quellcodes müssen in einem Array namens "code" und
-- die Dateinamen in einem Array namens "name" in der Vorlage angegeben werden
-- in der Table "options" können die Optionen
-- coptions, compiler, execargs, execstdin, wrap, compout, cpanel mit anderen Werten belegt werden
-- coptions wird für die Compiler-Optionen verwendet (standardmäßig "")
-- compiler enthält den Namen des verwendeten Compilers (standardmäßig "cg122")
-- execargs gibt an, ob die Execution Arguments angezeigt werden (standardmäßig "1")
-- execstdin gibt an, ob das Execution stdin angezeigt wird (standardmäßig "1")
-- wrap gibt an, ob es einen automatischen Zeilenumbruch gibt (standardmäßig "1")
-- compout gibt an, ob der Compiler Output angezeigt wird (standardmäßig "0")
-- cpanel gibt an, ob die Compiler Options angezeigt werden (standardmäßig "0")
-- Achtung: eine "1" bedeutet hier "false" und eine "0 "true"
-- Achtung: Innerhalb des Quellcodes nur doppelte Anführungszeichen verwenden,
-- da einfache Anführngszeichen in der URL für die einzelnen Werte verwendet werden.
function CompilerExplorerLink.createLink(frame)
local link = mw.html.create( "a" )
link:attr( "href", convert(frame.args.code,frame.args.name,frame.args.options) )
:wikitext( linkname )
return tostring( link )
end
return CompilerExplorerLink