File size: 3,379 Bytes
1e75d97 2e8c18d 1e75d97 5b3f6a4 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 1e75d97 2e8c18d 5b3f6a4 2e8c18d 5b3f6a4 2e8c18d 5b3f6a4 1e75d97 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
import gradio as gr
import subprocess, tempfile, os, resource, shutil
# ------------------------------------------------------------------
# 1️⃣ Función que compila y ejecuta el código C
# ------------------------------------------------------------------
def compile_and_run(code: str, stdin: str = "") -> str:
"""
Compila el código C recibido, lo ejecuta con límites de
recursos y devuelve stdout, stderr y exit-code.
"""
tmpdir = tempfile.mkdtemp(prefix="c_exec_")
c_path = os.path.join(tmpdir, "main.c")
bin_path = os.path.join(tmpdir, "main")
# Guardar el código fuente
with open(c_path, "w") as f:
f.write(code)
# Compilar
compile_proc = subprocess.run(
["gcc", c_path, "-O2", "-std=c11", "-pipe", "-o", bin_path],
capture_output=True,
text=True,
timeout=10
)
if compile_proc.returncode != 0:
shutil.rmtree(tmpdir, ignore_errors=True)
return f"❌ Error de compilación:\n{compile_proc.stderr}"
# Límites (CPU 2 s, RAM 128 MB)
def limit_resources():
resource.setrlimit(resource.RLIMIT_CPU, (2, 2))
resource.setrlimit(resource.RLIMIT_AS, (128 * 1024 * 1024,
128 * 1024 * 1024))
try:
run_proc = subprocess.run(
[bin_path],
input=stdin,
text=True,
capture_output=True,
timeout=2,
preexec_fn=limit_resources
)
except subprocess.TimeoutExpired:
shutil.rmtree(tmpdir, ignore_errors=True)
return "⏰ Tiempo de ejecución excedido (2 s)."
stdout, stderr = run_proc.stdout, run_proc.stderr
exit_code = run_proc.returncode
shutil.rmtree(tmpdir, ignore_errors=True)
result = f"⏹ Código de salida: {exit_code}\n"
if stdout:
result += f"\n📤 STDOUT\n{stdout}"
if stderr:
result += f"\n⚠️ STDERR\n{stderr}"
return result.strip()
# ------------------------------------------------------------------
# 2️⃣ Detección automática del lenguaje para gr.Code
# ('c' en Gradio ≥4, 'cpp' en Gradio 3)
# ------------------------------------------------------------------
def detect_c_language() -> str:
langs = getattr(gr.Code, "languages", [])
return "c" if "c" in langs else "cpp"
code_lang = detect_c_language()
# ------------------------------------------------------------------
# 3️⃣ Construcción de la interfaz
# ------------------------------------------------------------------
title = "Compilador C online (42 Edition)"
description = (
"Ejecuta fragmentos de **lenguaje C** con límite de recursos.\n"
"Disponible también como endpoint REST (`/run/predict`)."
)
demo = gr.Interface(
fn=compile_and_run,
inputs=[
gr.Code(language=code_lang, label="Código C"),
gr.Textbox(
lines=3,
placeholder="Entrada estándar (stdin)",
label="Stdin (opcional)"
),
],
outputs=gr.Textbox(label="Resultado"),
title=title,
description=description,
examples=[
["#include <stdio.h>\nint main(){puts(\"Hola 42!\");}", ""],
["#include <stdio.h>\nint main(){int a,b;scanf(\"%d %d\",&a,&b);"
"printf(\"%d\\n\",a+b);}", "3 4"],
],
)
if __name__ == "__main__":
demo.launch() |