File size: 4,259 Bytes
66f8fc1
e491165
 
 
66f8fc1
97eed3e
66f8fc1
57b6978
e491165
 
0814e7f
e491165
 
 
 
 
 
 
dc18db9
e491165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0814e7f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e491165
 
0814e7f
e491165
0814e7f
66f8fc1
e491165
 
136e7ac
 
 
 
90372e8
136e7ac
 
 
e491165
 
 
 
 
 
 
 
 
 
 
 
 
 
a238154
 
b08f4a6
0814e7f
e491165
 
 
 
0814e7f
e491165
 
 
 
 
 
 
 
 
 
329f9c0
 
e491165
 
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
106
107
108
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)