import gradio as gr import subprocess import tempfile from pathlib import Path EXAMPLE_CODE = open("/workspace/psychec/test.c", "r").read() def run_psychec(c_code: str): """Run PsycheC type inference on the provided C code.""" if not c_code.strip(): return "Please provide some C code.", "", "", "" with tempfile.TemporaryDirectory() as tmpdir: input_file = Path(tmpdir) / "input.c" input_file.write_text(c_code) try: result = subprocess.run( ["python2", "/workspace/psychec/reconstruct.py", str(input_file)], capture_output=True, text=True, timeout=30, cwd="/workspace/psychec" ) gen_header = Path(tmpdir) / "input_gen.h" fixed_c = Path(tmpdir) / "input_fixed.c" header_content = gen_header.read_text() if gen_header.exists() else "No header generated" fixed_content = fixed_c.read_text() if fixed_c.exists() else "No fixed file generated" log_output = result.stdout + ("\n" + result.stderr if result.stderr else "") if not log_output.strip(): log_output = "Type inference completed successfully." if result.returncode == 0 else "Type inference failed." compile_status = "" if fixed_c.exists(): try: compile_result = subprocess.run( ["cc", "-c", str(fixed_c)], capture_output=True, text=True, cwd=tmpdir ) if compile_result.returncode == 0: compile_status = "Compilation successful." else: compile_status = f"Compilation failed: {compile_result.stderr.strip()}" except Exception as e: compile_status = f"Compilation error: {e}" else: compile_status = "No fixed file to compile." return log_output, header_content, fixed_content, compile_status except subprocess.TimeoutExpired: return "Error: Type inference timed out after 30 seconds.", "", "", "" except Exception as e: return f"Error: {e}", "", "", "" def create_demo(): with gr.Blocks(title="PsycheC Type Inference") as demo: gr.Markdown("""# 🔍 PsycheC Type Inference Analyze C code and infer missing type declarations. PsycheC will generate a header file with inferred types and a fixed C file. Note: The parser gets stuck on some attributes including `__cdecl`. """) gr.Markdown( ) with gr.Row(): with gr.Column(): code_input = gr.Code( label="C Source Code", language="c", value=EXAMPLE_CODE, lines=15 ) run_btn = gr.Button("Run Type Inference", variant="primary") with gr.Column(): header_output = gr.Code(label="Generated Header (_gen.h)", language="c", lines=10) fixed_output = gr.Code(label="Fixed C File (_fixed.c)", language="c", lines=10) log_output = gr.Textbox(label="Output Log", lines=1) compile_output = gr.Textbox(label="Compilation Status", lines=5) run_btn.click( fn=run_psychec, inputs=[code_input], outputs=[log_output, header_output, fixed_output, compile_output] ) gr.Markdown( "---\n" "Based on [PsycheC](https://github.com/ltcmelo/psychec) - " "A compiler frontend for C with type inference capabilities.\n\n" "Docker image: [psychec-typeinference-docker](https://github.com/edmcman/psychec-typeinference-docker)" ) return demo if __name__ == "__main__": demo = create_demo() demo.launch(server_name="0.0.0.0", server_port=7860)